• [Go] 浅谈 Golang Chan 通信与死锁:all goroutines are asleep deadlock


     

    Channel创建方式:

      var c1 chan [value type]

      c1 = make([channel type] [value type], [capacity])

     

      [value type] 定义的是 Channel 中所传输数据的类型。

      [channel type] 定义的是 Channel 的类型,其类型有以下三种:

        "chan" 可读可写 : chan int 则表示可读写 int 数据的 channel

        "chan<-" 仅可写 : chan<- float64 则表示仅可写64位 float 数据的 channel

        "<-chan" 仅可读 : <-chan int 则表示仅可读 int 数据的 channel

      [capacity] 是一个可选参数,其定义的是 channel 中的缓存区 (buffer)。

        如果不填则默认该 channel 没有缓冲区 (unbuffered)。

        对于没有缓冲区的 channel,消息的发送和收取必须能同时完成,否则会造成阻塞并提示死锁错误。

        

    Channel死锁:对 channel 的发送和接收动作永远不会同时发生,从而阻塞造成死锁。

            fatal error: all goroutines are asleep - deadlock!

     

          避免死锁方式1:使用goroutine并发执行。

                     通过 go 语句定义发送操作的方程在另一个协程并发运行,chan读取没有数据时会阻塞等待,从而能够解决死锁

          避免死锁方式2:使用 buffer。

                  为 channel 添加一个缓冲区(buffer),这样只要 buffer 没有用尽,阻塞就不会发生,死锁也不会发生。

          

          Example:chan.go

          同样的,在 select 控制结构中,如果两个 channel 都阻塞且没有 default 流程分支时,也将产生死锁(deadlock)。

           Example:select.go

     

    不同于传统的多线程通过共享内存来通信,CSP讲究的是“以通信的方式来共享内存。

    普通的线程并发模型,就是像Java、C++、或者Python,他们线程间通信都是通过共享内存的方式来进行的。

    非常典型的方式就是,在访问共享数据(例如数组、Map、或者某个结构体或对象)的时候,通过锁来访问,因此,在很多时候,衍生出一种方便操作的数据结构,叫做“线程安全的数据结构”。

    例如Java提供的包”java.util.concurrent”中的数据结构。Go中也实现了传统的线程并发模型。

    Go的CSP并发模型,是通过 goroutine 和 channel 来实现的。

    Refer:all goroutines are asleep

    Link:https://www.cnblogs.com/farwish/p/15843402.html

  • 相关阅读:
    编译 | 更新标准库_交叉编译工具链
    论文 | 图文_学科
    编码 | 二进制格式设计方案
    图片 | 图片上传管理
    进程 | 查询进程中包含多少线程
    第二周02:Fusion ICP逐帧融合
    exe文件当前目录搜索文件
    第一周:读取XML深度数据并将其重建为三维点云
    第二周:01 ICP迭代交互
    C++文件读写(转载)
  • 原文地址:https://www.cnblogs.com/farwish/p/15843402.html
Copyright © 2020-2023  润新知