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.

它同时具备2个特性:
1. 消息传递
2. 同步
 
channel的实现,都在$GOROOT/src/pkg/runtime/chan.c里
 
它是通过共享内存实现的
struct Hchan {
}
 
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的实现
}
参考:http://www.voidcn.com/blog/kjfcpua/article/p-2921075.html
http://shanks.leanote.com/post/%E6%B7%B1%E5%BA%A6%E5%89%96%E6%9E%90channel

golang channel本质——共享内存的更多相关文章

  1. golang channel 使用总结

    原文地址 不同于传统的多线程并发模型使用共享内存来实现线程间通信的方式,golang 的哲学是通过 channel 进行协程(goroutine)之间的通信来实现数据共享: Do not commun ...

  2. 三分钟掌握共享内存 & Actor并发模型

    吃点好的,很有必要.今天介绍常见的两种并发模型: 共享内存&Actor 共享内存 面向对象编程中,万物都是对象,数据+行为=对象: 多核时代,可并行多个线程,但是受限于资源对象,线程之间存在对 ...

  3. golang channel原理

    channel介绍 channel一个类型管道,通过它可以在goroutine之间发送和接收消息.它是Golang在语言层面提供的goroutine间的通信方式. 众所周知,Go依赖于称为CSP(Co ...

  4. golang channel底层结构和实现

    一.介绍 Golang 设计模式: 不要通过共享内存来通信,而要通过通信实现内存共享 channel是基于通信顺序模型(communication sequential processes, CSP) ...

  5. 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏

    一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...

  6. C扩展 从共享内存shm到memcache外部内存

    引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...

  7. Android 匿名共享内存Java接口分析

    在Android 匿名共享内存驱动源码分析中介绍了匿名共享内存的驱动实现过程,本文在Android匿名共享内存驱动基础上,介绍Android匿名共享内存对外Android系统的匿名共享内存子系统的主体 ...

  8. Win3内存管理之私有内存跟共享内存的申请与释放

    Win3内存管理之私有内存跟共享内存的申请与释放 一丶内存简介私有内存申请 通过上一篇文章.我们理解了虚拟内存与物理内存的区别. 那么我们有API事专门申请虚拟内存与物理内存的. 有私有内存跟共享内存 ...

  9. Linux 程序设计1:深入浅出 Linux 共享内存

    笔者最近在阅读Aerospike 论文时,发现了Aerospike是利用了Linux 共享内存机制来实现的存储索引快速重建的.这种方式比传统利用索引文件进行快速重启的方式大大提高了效率.(减少了磁盘 ...

随机推荐

  1. USACO 1.3 Ski Course Design - 暴力

    Ski Course Design Farmer John has N hills on his farm (1 <= N <= 1,000), each with an integer ...

  2. Java DecimalFormat 用法(数字格式化)

    我们经常要将数字进行格式化,比如取2位小数,这是最常见的.Java 提供 DecimalFormat 类,帮你用最快的速度将数字格式化为你需要的样子.下面是常用的例子: import java.tex ...

  3. P4396 [AHOI2013]作业

    题目链接 luogu4396 思路 唯有水题暖人心 咕了4天,今天跟着std对拍才做出来不得不说题解真的水的一批 先离散化一下 第一问差分询问,权值树状数组套一套就好了 \(nlog_{n}\) 第二 ...

  4. Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 1)

    A - Toy Train 很显然,一个站有多少个糖,那么就要从这个点运多少次.设第i个点有\(a_i\)个糖,那么就要转\(a_i-1\)圈,然后再走一段.很显然最后一段越小越好. 然后枚举起点后, ...

  5. JDK tools之jps和jstack诊断Java程序

    大部分Java开发者可能知道有这么个工具,但是没怎么用过,每次还得百度一下.我也是之一 -_-!!. 每次遇到

  6. Mui --- 弹出菜单

    mui框架内置了弹出菜单插件,弹出菜单显示内容不限,但必须包裹在一个含.mui-popover类的div中,如下即为一个弹出菜单内容: <div id="popover" c ...

  7. hdu 3579 Hello Kiki 不互质的中国剩余定理

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  8. Jmeter 抓app包 抓到一半不好用了

    错误描述: java.net.ConnectException: Connection refused (Connection refused) at java.net.PlainSocketImpl ...

  9. python2 安装scrapy出现错误提示解决办法~

    首先:set STATICBUILD=true && pip install lxml 安装环境: windows7操作系统,已经正确安装python,pip. 使用pip功能安装Sc ...

  10. 【Golang 接口自动化07】struct转map的三种方式

    背景 我们在前面介绍过怎么使用net/http发送json或者map数据,那么它能不能直接发送结构体数据呢?我们今天一起来学习结构体struct转map的三种方法,为后续做铺垫. struct转map ...