奇怪的channel 的笔记

channel 不仅能够控制数据传输,还可以控制执行流。

1.  关闭的channel从来都不会阻塞

关闭的channel不能传数据但是可以接受数据,例子

```

package main

import "fmt"

func main() {
ch := make(chan bool, 2)
ch <- true
ch <- true
close(ch)

for i := 0; i < cap(ch) +1 ; i++ {
v, ok := <- ch
fmt.Println(v, ok)
}
}


```

接受的是默认空值。

替代性地,可以用range

```

package main

import "fmt"

func main() {
ch := make(chan bool, 2)
ch <- true
ch <- true
close(ch)

for v := range ch {
fmt.Println(v) // called twice
}
}


```

当channel干枯后就会跳出循环流程,这个循环会执行两次。

但是select才是真功夫。

```

package main

import (
"fmt"
"sync"
"time"
)

func main() {
finish := make(chan bool)
var done sync.WaitGroup
done.Add(1)
go func() {
select {
case <-time.After(1 * time.Hour):
case <-finish:
}
done.Done()
}()
t0 := time.Now()
finish <- true // send the close signal
done.Wait() // wait for the goroutine to stop
fmt.Printf("Waited %v for goroutine to stop\n", time.Since(t0))
}


```

在调用done之前是不会真的等一个小时的。

但是这个程序也会有问题。就是finish
不是带缓冲的。如果接受者忘了加上select里面的语句的话,就会阻塞了。(比如开了100个goroutine,但是这送了99次之类的)

利用关闭了的channel是永远可以接受的特性,把代码改成下面这样。

```

package main

import (
"fmt"
"sync"
"time"
)

func main() {
const n = 100
finish := make(chan bool)
var done sync.WaitGroup
for i := 0; i < n; i++ {
done.Add(1)
go func() {
select {
case <-time.After(1 * time.Hour):
case <-finish:
}
done.Done()
}()
}
t0 := time.Now()
close(finish) // closing finish makes it ready to receive
done.Wait() // wait for all goroutines to stop
fmt.Printf("Waited %v for %d goroutines to stop\n", time.Since(t0), n)
}


```

话说这和没有finish通道不是一个效果么?不管了

实际上如果在通道里的东西,你从来不用,应该构造成空的结构体,就像下面的例子。

```

package main

import (
"fmt"
"sync"
"time"
)

func main() {
finish := make(chan struct{})
var done sync.WaitGroup
done.Add(1)
go func() {
select {
case <-time.After(1 * time.Hour):
case <-finish:
}
done.Done()
}()
t0 := time.Now()
close(finish)
done.Wait()
fmt.Printf("Waited %v for goroutine to stop\n", time.Since(t0))
}


```

说明这个channel不包含东西。

2.  nil channel 永远都是阻塞的。

```

package main

func main() {
var ch chan bool
ch <- true // blocks forever
}

```

这是一个死锁。

接受的话也是死锁。
```

package main

func main() {
var ch chan bool
<- ch // blocks forever
}


```

先看到这,明天再来。

奇怪的channel 的笔记,布布扣,bubuko.com

时间: 2024-12-14 18:42:52

奇怪的channel 的笔记的相关文章

maxscript Map Channel 相关笔记

3dmax 中的<Map Channel>可以保存0-99共100个编号,max中通过这些通道可以取得顶点颜色通道,每一个UV坐标通道信息.Map Channel的0号通道通常代表模型的顶点颜色 :1号通道为默认的UV纹理通道:其余编号用户启用了其他纹理通道则会激活. 1.meshop.getnumcpvverts  函数可获取一个模型网格的颜色顶点数量.对应模型Mapping Methods的<Channel 0>.但前提是该模型指定了顶点颜色,如果不指定顶点颜色 getnumc

[PR &amp; ML 3] [Introduction] Probability Theory

虽然学过Machine Learning和Probability今天看着一part的时候还是感觉挺有趣,听惊呆的,尤其是Bayesian Approach.奇怪发中文的笔记就很多人看,英文就没有了,其实我觉得英文的写得更好呀...囧...一边看一边写一边实现,好慢,求同道中人啊...

[linux]ubuntu 下安装RMySQL包

http://downloads.mysql.com/docs/connector-odbc-en.pdf http://blog.csdn.net/ixidof/article/details/5958904 http://askubuntu.com/questions/446483/how-to-investigate-mariadb-unixodbc-issue-further http://stackoverflow.com/questions/27030590/is-there-com

Java如何处理多线程的数据同步问题

在这里写这种文章好奇怪,先用作笔记吧 Java中有如下的方法来处理代码块的并发访问问题:一是关键字synchronized二是加锁(锁对象,条件对象) Java给每一个对象都提供了一个内部锁,在方法的定义中加上关键字synchronized后,那么对象的锁将保护整个方法.也就是说下面两种写法是等价的:public synchronized void method(){......} public void method(){this.intrinsickLock.lock();try{.....

奇怪的笔记酱

//摘自洛谷: //0x3f3f3f3f还能给我们带来一个意想不到的额外好处:如果我们想要将某个数组清零,我们通常会使用memset(a,0,sizeof(a))这样的代码来实现(方便而高效) //但是当我们想将某个数组全部赋值为无穷大时(例如解决图论问题时邻接矩阵的初始化),就不能使用memset函数而得自己写循环了 (写这些不重要的代码真的很痛苦) //我们知道这是因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0 //现在好了,如果我们将无穷大设为0x3f3f3f3f

Flume NG 学习笔记(五)Sinks和Channel配置

一.HDFS Sink Flume Sink是将事件写入到Hadoop分布式文件系统(HDFS)中.主要是Flume在Hadoop环境中的应用,即Flume采集数据输出到HDFS,适用大数据日志场景. 目前,它支持HDFS的文本和序列文件格式,以及支持两个文件类型的压缩.支持将所用的时间.数据大小.事件的数量为操作参数,对HDFS文件进行关闭(关闭当前文件,并创建一个新的).它还可以对事源的机器名(hostname)及时间属性分离数据,即通过时间戳将数据分布到对应的文件路径. HDFS目录路径可

Flume NG 学习笔记(十) Transaction、Sink、Source和Channel开发

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 一.Transaction interface Transaction接口是基于flume的稳定性考虑的.所有主要的组件(sources.sinks.channels)都必须使用Flume Transaction.我们也可以理解Transaction接口就是flume的事务,sources和sinks的发送数据与接受数据都是在一个Transaction里完成的. 从上图中可以看出,一个Transaction在Channel实

Java基础知识强化之IO流笔记76:NIO之 Channel(通道)之间的数据传输

1. 在Java NIO中,如果两个通道中有一个是FileChannel,那你可以直接将数据从一个channel(译者注:channel中文常译作通道)传输到另外一个channel. (1)transferFrom(): FileChannel的 transferFrom()方法可以将数据 从 源通道 传输到 FileChannel中(译者注:这个方法在JDK文档中的解释为将字节从给定的可读取字节通道传输到此通道的文件中).下面是一个简单的例子: 1 RandomAccessFile fromF

nsq源码阅读笔记之nsqd(四)——Channel

与Channel相关的代码主要位于nsqd/channel.go, nsqd/nsqd.go中. Channel与Topic的关系 Channel是消费者订阅特定Topic的一种抽象.对于发往Topic的消息,nsqd向该Topic下的所有Channel投递消息,而同一个Channel只投递一次,Channel下如果存在多个消费者,则随机选择一个消费者做投递.这种投递方式可以被用作消费者负载均衡. Channel从属于特定Topic,可以认为是Topic的下一级.在同一个Topic之下可以有零个