11

理解golang的channel

 3 years ago
source link: https://doumao.cc/index.php/%E7%BC%96%E7%A8%8B/%E7%90%86%E8%A7%A3golang%E7%9A%84channel.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

channel是golang里很重要的一种数据结构

channel的特性

0QRSAO.jpg
0QRSAO.jpg

channel内部实现

buffered channel在底层使用一个struct来实现,使用一个环形缓冲区circular queue来保存元素。

0QRMCQ.jpg

向channel发送值

0QRU5F.jpg
0QRU5F.jpg

channel的buffer已满

0QRdC4.jpg
0QRdC4.jpg

从channel接收值

0QRcVK.jpg
0QRcVK.jpg

ps:

0QRh2d.jpg
0QRh2d.jpg
使用make来创建channel时,go在堆上分配一个hchan struct,然后初始化它,最后返回的是一个指向hchan struct的指针。

channel发送和接收值的过程

buffered channel之所以能够goruntine安全,因为每次sendreceive时,都会对结构体内的mutex上锁。

下面是send的过程。

0QWkiF.jpg
0QWkiF.jpg
0QWiIU.jpg
0QWiIU.jpg
0QWPaT.jpg
0QWPaT.jpg

下面是receive的过程。

0QW8RH.jpg
0QW8RH.jpg
0QW3Je.jpg
0QW3Je.jpg
0QW1iD.jpg
0QW1iD.jpg

channel如何暂停(Pause)和恢复(Resume) goroutine

0lCoV0.jpg
0lCoV0.jpg

先了解下Go的调度器和GMP

0lPJLn.jpg
0lPJLn.jpg

goroutine可以看做是用户态线程,goroutine由go运行时创建和管理,被调度器调度到系统线程。

0lPxSg.jpg
0lPxSg.jpg

暂停(Pause)goroutine

0li3tK.jpg
0li3tK.jpg

可以看到,当channel满时,被阻塞的只是goroutine,系统线程仍处在运行状态。

恢复(Resume)goroutine

01cS4e.jpg
01cS4e.jpg
01cC3d.jpg
01cC3d.jpg

当从一个满的channel接收值时

01cwvR.jpg
01cwvR.jpg
01cuCQ.jpg
01cuCQ.jpg
01cZE8.jpg
01cZE8.jpg
01ceUS.jpg
01ceUS.jpg
01cm4g.jpg
01cm4g.jpg

GopherCon 2017: Kavya Joshi - Understanding Channels
Kavya Joshi - Understanding Channels.pdf


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK