golang 并发 chan
来源:互联网 发布:蚁群算法python实现 编辑:程序博客网 时间:2024/05/22 06:05
channels 是 goroutines之间通信的工具, 可以理解为管道, 虽然go也提供共享变量的方式, 但是更加推荐使用channel
func TestChan(t *testing.T) {c := make(chan int)go func() {c <- 48}()fmt.Println(<- c)// 保持持续运行holdRun()}func holdRun() {time.Sleep(1 * time.Hour)}
c := make(chan int) 声明一个 传输整形 的unbuffer chan,(接收消息和发送消息者将会阻塞,直到channel ”可用“)
<- 操作符用来接受和发送消息 chan <- 48 发送“48“ 进入管道, <-chan 接收消息
如果: c: = make(chan int, 10) 声明一个 传输整形 的buffer chan, 容量为10, 接收消息将可以立即返回除非channel里面没有消息, 发送者返回除非容量满
func TestDeadLock(t *testing.T) {c := make(chan int)c <- 42val := <-cfmt.Println(val)}func TestDeadLock1(t *testing.T) {c := make(chan int)//c := make(chan int, 0)go func() {c <- 48}()val := <-cfmt.Println(val)}func TestDeadLock2(t *testing.T) {c := make(chan int, 1)c <- 42val := <-cfmt.Println(val)}对于方法, TestDeadLock 将:fatal error: all goroutines are asleep - deadlock! 因为c <- 42 将会一直阻塞,直到出现消费者, 无容量的chan是同步, 正确的写法是 TestDeadLock1 这样不会死锁, 或者 TestDeadLock2 也不会死锁
func TestChan(t *testing.T) {c := make(chan int, 10)go func() {c <- 48c <- 96time.Sleep(2 * time.Second)c <- 200}()time.Sleep(1 * time.Second)for v := range c {fmt.Println(v)}// 保持持续运行holdRun()}chan 可以配合 range 使用, 相当于每次foreach 每次去取一次
func TestDChan(t *testing.T) {c := make(chan int)go f1(c)holdRun()}func f1(c chan <- int) {c <- 0<- c }f1的参数类型是 chan <- int 表明 这个chan单向的, 只能用来接收。 f1函数编译错误:invalid operation: <-c (receive from send-only type chan<- int)
相对应的发送的chan : c <-chan string
select 关键字可以和 chan使用, 类似与switch
func TestSelect(t *testing.T) {c1 := make(chan int)c2 := make(chan int, 10)c3 := make(chan int, 20)go func(c1, c2, c3 chan<- int) {for {time.Sleep(1 * time.Second)c1 <- 1time.Sleep(1 * time.Second)c1 <- 1time.Sleep(1 * time.Second)c1 <- 2time.Sleep(1 * time.Second)c1 <- 3}}(c1, c2, c3)for {select {case int1 := <-c1:fmt.Println("c1 value :", int1)case int2 := <-c2:fmt.Println("c2 value :", int2)case int3 := <-c3:fmt.Println("c3 vaule :", int3)case <-time.After(2 * time.Second):fmt.Println("timeount")}}}select 将阻塞直到有一个chan ready或者 超时,即 time.After
select {case int1 := <-c1:fmt.Println("c1 value :", int1)case int2 := <-c2:fmt.Println("c2 value :", int2)case int3 := <-c3:fmt.Println("c3 vaule :", int3)default:fmt.Println("nothing ready")}
select 将不会阻塞, 直接执行 default
附 :
time.Afer 实现:
func After(d Duration) <-chan Time {return NewTimer(d).C}
func NewTimer(d Duration) *Timer {c := make(chan Time, 1)t := &Timer{C: c,r: runtimeTimer{when: when(d),f: sendTime,arg: c,},}startTimer(&t.r)return t}
NewTimer 返回一个 timer (timer是一个一次性时间,d 时间后 发送当前时间给 C) , 由于C在此之前会一直阻塞。从而达到超时的效果
1 0
- golang 并发 chan
- golang并发编程实践 -- 简单生产者消费者(with chan)
- Golang之chan/goroutine
- 关于GOLANG的chan
- golang chan的运用
- golang使用chan
- golang chan 使用例子
- Golang 关于通道 Chan 详解
- golang基础-goroutine初识、chan存取、goroutine和chan相结合、关闭chan、range取、单元测试
- C++实现golang chan 版本一
- golang chan make前后值比较
- golang chan 单项通道与多项通道
- 【golang】signal和chan结合使用
- golang chan 使用的一个坑
- golang并发
- golang 并发
- 利用golang中的chan数据类型来实现简易连接池
- Golang 的 map,slic 转 json 注意 chan
- MeasureSpec
- 关于java格式化数据,保留两位小数不精准的问题
- 如何快速启动 Android 模拟器
- 进度选择器
- Oracle连接数查看
- golang 并发 chan
- PHP_SELF、 SCRIPT_NAME、 REQUEST_URI区别
- Power of Three
- C++虚函数的底层实现原理
- Android 自定义View
- Contacts(CNContact)
- hdoj 5489 Removed Interval 【线段树维护LIS or LIS变形】
- 基于Ubuntu 14.04和CUDA 7.0为基础的caffe环境配置
- Python的安装