为什么Channel的sz_max为0时还能往里面put!


#1

在学习通道绑定时,我发现当我在REPL写下 c=Channel(0),返回的是Channel{Any}(sz_max:0,sz_curr:0)

创建一个协程任务
julia> task=@async foreach(i->put!(c,i),1:4)
Task (runnable) @0x00007f3f1015dfc0

此时绑定通道
julia>bind(c,task)
Channel{Any}(sz_max:0,sz_curr:1)
sz_max居然小于sz_curr了

取出Channel中数据

julia> for i in c
           @show i
       end

返回

i = 1
i = 2
i = 3
i = 4

这样以后查看c

julia> c
Channel{Any}(sz_max:0,sz_curr:0)

sz_curr又变为0

如果直接对c进行put!的话,会造成阻塞,而在通道绑定时却没有这样的情况,请问这是为什么


#2

1 无缓冲的Channel有元素的时候sz_curr当然是1
2 阻塞你的不是put!,而是for循环里面的take!。读完最后一个元素之后,因为没有新元素放入,它会一直阻塞
3 bind的作用是当Task终止之后自动关闭Channel,这样take!就会返回,从而退出for循环。如果你不想bind,你也可以

task=@async begin foreach(i->put!(c,i),1:4);close(c) end

话说我记得上次跟你说过了take!是会阻塞的…多看文档


#3


我没有说清楚,
这才是我说的直接用put!造成的阻塞,我说的好像不是for循环里的阻塞


#4

不是说了无缓冲吗
无缓冲Channelput!在任何时候都是阻塞的(因为容量为零),只有当读走一个元素后put!才会返回


#5

put!会阻塞进程,但是你放在协程里面,阻塞的是协程。

sz_curr增加与bind无关,调用put!的时候已经增加了。
无缓冲的Channel, sz_curr的值对应put!协程的个数,不是真的缓存了数据