golang channel本质——共享内存
channel是golang中很重要的概念,配合goroutine是golang能够方便实现并发编程的关键。channel其实就是传统语言的阻塞消息队列,可以用来做不同goroutine之间的消息传递,由于goroutine是轻量级的线程能够在语言层面调度,所以channel在golang中也常被用来同步goroutine。
一般channel的声明形式为:var chanName chan ElementType
ElementType指定这个channel所能传递的元素类型。
定义一个channel也很简单,直接使用内置的函数make()即可:
ch := make(chan int,bufferSize) //bufferSize为缓冲区的大小,可以不传递该值代表不带缓冲区的channel
消息传递
带有缓冲区的channel一般用来做不同goroutine之间的消息传递。最经典的解释莫过于生产者-消费者了。生产者向channel中写数据,如果channel缓冲区已满,则生产者会被阻塞直到消费者消费缓冲区中的数据后才能被唤醒。
消费者从channel中读取数据,如果缓冲区中没有任何数据则消费者会阻塞直到生产者将数据写入才能被唤醒。
假设我们有30个学生做作业,做完作业后由一个老师批改作业。用go怎么实现呢,我们首先定义一个带有缓冲区HomeWork chan(缓冲区的大小与学生数目相同,主要是为了防止学生提交作业时阻塞),学生做完作业向hwChan中发送数据,老师等待hwChan中有数据就取出学生作业然后批改。
channel是消息传递的机制,用于多线程环境下lock free synchronization.
ch := make(chan interface{}, )
具体的实现是chan.c里的 Hchan* runtime·makechan_c(ChanType *t, int64 hint)
此时,hint=, t=interface{}
它完成的任务就是:
分配hint * sizeof(t) + sizeof(Hchan)的内存空间[也就是说,buffered chan的buffer越大,占用内存越大]
ch <-
就会调用 void runtime·chansend(ChanType *t, Hchan *chan, byte *ep, bool *pres)
lock(chan)
如果chan是buffer chan {
比较当前已经放入buffer里的数据是否满了A
如果没有满 {
把ep(要放入到chan里的数据)拷贝到chan的内存区域 (此区域是sender/recver共享的)
找到receiver goroutine, make it ready, and schedule it to recv
} else {
已经满了
把当前goroutine状态设置为Gwaiting
yield
}
} else {
// 这是blocked chan
找到receiver goroutine (channel的隐喻就是一定存在多个goroutine)
让该goroutine变成ready (之前是Gwaiting), 从而参与schedule,获得控制权
具体执行什么,要看chanrecv的实现
}
golang channel本质——共享内存的更多相关文章
- golang channel 使用总结
原文地址 不同于传统的多线程并发模型使用共享内存来实现线程间通信的方式,golang 的哲学是通过 channel 进行协程(goroutine)之间的通信来实现数据共享: Do not commun ...
- 三分钟掌握共享内存 & Actor并发模型
吃点好的,很有必要.今天介绍常见的两种并发模型: 共享内存&Actor 共享内存 面向对象编程中,万物都是对象,数据+行为=对象: 多核时代,可并行多个线程,但是受限于资源对象,线程之间存在对 ...
- golang channel原理
channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...
- golang channel底层结构和实现
一.介绍 Golang 设计模式: 不要通过共享内存来通信,而要通过通信实现内存共享 channel是基于通信顺序模型(communication sequential processes, CSP) ...
- 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏
一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...
- C扩展 从共享内存shm到memcache外部内存
引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...
- Android 匿名共享内存Java接口分析
在Android 匿名共享内存驱动源码分析中介绍了匿名共享内存的驱动实现过程,本文在Android匿名共享内存驱动基础上,介绍Android匿名共享内存对外Android系统的匿名共享内存子系统的主体 ...
- Win3内存管理之私有内存跟共享内存的申请与释放
Win3内存管理之私有内存跟共享内存的申请与释放 一丶内存简介私有内存申请 通过上一篇文章.我们理解了虚拟内存与物理内存的区别. 那么我们有API事专门申请虚拟内存与物理内存的. 有私有内存跟共享内存 ...
- Linux 程序设计1:深入浅出 Linux 共享内存
笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...
随机推荐
- C_Learning (1)
/数据类型及占用字节 char 1个字节{-128~127} int 2.4个字节,取决于平台是16位还是32位机子{-65536~65535} short int 2个字节{-32768 ...
- 20145104张家明 《Java程序设计》第四次实验设计
20145104张家明 <Java程序设计>第四次实验设计 这第四次实验报告 我们开始着手安卓了 在电脑上安装了安卓虚拟机
- 关于cp命令的编写
关于cp命令的编写 娄老师在课上详细的讲了命令who的编写过程~对此,我很有启发!于是想亲自动手试试~ 有什么不足的地方请大家提出来! Learning by doing ~ 做中学,真的只有自己动手 ...
- CEF之CefSettings设置日志等级
CefSettings结构体允许定义全局的CEF配置,经常用到的配置项如下: single_process 设置为true时,Browser和Renderer使用一个进程.此项也可以通过命令行参数“s ...
- @Transactional引起的NullPointerException
https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-Transactional-NullPointerException ...
- UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 0
Windows 7/8/10机器上安装Python 2.7后,下载一些Package包进行setup时总是报错UnicodeDecodeError,如下: File "C:/Python27 ...
- 如何在Twitter开发者平台上注册自己的应用
1.打开twitter的官网https://dev.twitter.com,如果还没有注册账号的,需要注册账号,已经注册账号的,请先登录:2.选择其中的My apps,如下图: 3.进去界面,选择Cr ...
- C语言中生产随机数 rand()函数
参考资料:C语言中产生随机数 一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdl ...
- TCGA系列--LncMAP
LncMAP:http://www.bio-bigdata.com/LncMAP/index.jsp
- c++ 判断数组元素是否都是奇数(all_of)
#include <iostream> // std::cout #include <algorithm> // std::all_of #include <array& ...