Goroutines (一)

Goroutines

CSP communicating sequential processes

Go 语言中,每一个并发执行单元叫做一个goroutine,语法上仅需要在一个普通函数或方法调用前加上关键字go。

f() //正常调用

go f() //开启一个goroutine

一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值信息。每个channel都有一个特殊的类型,也就是channels可发送数据的类型。

ch := make(chan int) // ch has type 'chan int'

ch = make(chan int, 0) // unbuffered channel
ch = make(chan int, 3) // buffered channel with capacity 3

和map类似,channel也对应一个make创建的底层数据结构的引用

当我们复制一个channel或用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者和被调用者将引用同一个channel对象。和其它的引用类型一样,channel的零值也是nil。
两个相同类型的channel可以使用==运算符比较。如果两个channel引用的是相同的对象,那么比较的结果为真。一个channel也可以和nil进行比较。

ch <- x a send statement receive expression in an assignment <-ch statement; result is discarded < code></->

Channel支持close操作,用于关闭channel,随后对基于该channel的任何发送操作都将导致panic异常。一个已经被close过的channel进行接收操作依然可以接受到之前已经成功发送的数据;如果channel中已经没有数据的话将产生一个零值的数据。

关闭一个channel

close(ch)

一个基于无缓存Channel的发送操作将导致发送者goroutine阻塞,直到另一个goroutine在相同的Channel上执行接收操作,当发送的值通过Channels成功传输之后,两个goroutine可以继续执行后面的语句。反之,如果接收操作先发生,那么接收者goroutine也将阻塞,直到有另一个goroutine在相同的Channels上执行发送操作。

基于无缓存Channels的发送和接收操作将导致两个goroutine做一次同步操作,因此,无缓存的Channel 也被称为同步Channel ,当通过一个无缓存Channel发送数据时,接收者收到数据发生在再次唤醒发送者goroutine之前(happens before)

消息事件 利用channel进行通信,通知另一个协程事情已经做完

func main() {
    var i = 0
    done := make(chan struct{})
    go func() {
        for i < 10 {
            fmt.Printf("i = %d\n", i)
            i++
            if i == 10 {
                fmt.Printf("done\n")
                done <- struct{}{} } time.sleep(100 * time.millisecond) }() <-done < code></->

一个Channel的输出作为下一个Channel的输入,当一个channel被关闭后,再向该channel发送数据将导致panic异常。当一个被关闭的channel中已经发送的数据都被成功接收后,后续的接收操作将不再阻塞,它们会立即返回一个零值。

func main() {
    naturals := make(chan int)
    squares := make(chan int)

    // Counter
    go func() {
        for x := 0; ; x++ {
            if x < 100 {
                naturals <- x } else { close(naturals) break 这里需要break 重复关闭一个channel将导致panic异常 }() squarer go func() for :="<-naturals" squares <- * printer (in main goroutine) fmt.println(<-squares) 程序会无休止的收到0值 < code></->

channel 接收的方式可以改进

&#x5229;&#x7528;&#x7B2C;&#x4E8C;&#x4E2A;&#x8FD4;&#x56DE;&#x503C;&#x5224;&#x65AD; channel &#x662F;&#x5426;&#x5173;&#x95ED;
go func() {
    for {
        x, ok := <-naturals if !ok { break } squares <- x * close(squares) }() l利用for range 形式 for :="range" fmt.println(x) < code></-naturals>

试图重复关闭一个channel将导致panic异常,试图关闭一个nil值的channel也将导致panic异常。关闭一个channels还会触发一个广播机制

类型chan

Original: https://www.cnblogs.com/arvinhuang/p/15220515.html
Author: 平凡键客
Title: Goroutines (一)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620175/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Tomcat解压war包错误

    最近一个项目由于需要频繁发布,我又懒得把项目的war包和同名文件夹一起复制,一般发布war包等待war包自动解压来发布站点,当发布了39次时,war包解压异常最显著的信息是原来解压…

    数据库 2023年6月9日
    0110
  • haproxy

    haproxy 一.haproxy简介 二.负载均衡 三.haproxy安装 1.yum安装 2.源码安装 2.1 配置文件解析 2.2时间格式 2.3 全局global 2.4 …

    数据库 2023年6月14日
    0112
  • Mac IDEA 最常用快捷键(详解版)

    学习背景 公司同事让我提供一个简单的 rpc 接口,然后他坐在我旁边看着我写,写的过程中他不断打断我,比如我在代码换行时,如果光标不在下一行行首或者这行的行尾,我就会先移动光标到行…

    数据库 2023年6月6日
    0134
  • Windows安装mysql数据库

    一般我安装mysql用以下两个方法: 一.phpstudy环境下的mysql安装 只需将mysql的bin目录配置到系统环境变量即可, 输入默认密码root即可登录 二.本地直接安…

    数据库 2023年5月24日
    0127
  • 2020年十大最佳自动化测试工具

    Best Automation Testing Tools for 2020 对更快交付高质量软件(或”快速质量”)的需求要求组织以敏捷,持续集成(CI)和…

    数据库 2023年6月9日
    0107
  • ElasticSearch详解

    什么是ElasticSearch ElasticSearch是一款非常强大的、基于Lucene的开源搜素及分析引擎;它是一个实时的分布式搜索分析引擎。它通常被用作全文检索、结构化搜…

    数据库 2023年6月6日
    0142
  • [Unity]如何将两个物体不留缝隙的精确贴合在一起

    比如说想让正方体精确贴合到墙上: 按住V,选中正方体,此时开启了 顶点吸附功能,正方体上的变换工具会变成以某个顶点为变换中心,如下图所示: 拖动中间的白色小方块,就会将正方体的该顶…

    数据库 2023年6月16日
    0125
  • ReentrantLock 公平锁源码 第1篇

    ReentrantLock 1 这篇还是接着ReentrantLock的公平锁,没看过第0篇的可以先去看上一篇https://www.cnblogs.com/sunankang/p…

    数据库 2023年6月16日
    0144
  • Spring boot 项目配置 Maven 资源文件分离打包

    需要引入三个Maven插件: maven-jar-plugin:用于打包代码,并去除不需要一起打包的resource文件 maven-assembly-plugin:主要用来打压缩…

    数据库 2023年6月9日
    0111
  • postman自动化测试

    postman做接口的自动化测试case 记录一次自动化测试的工作,以及该过程中对于测试设计的一些思考。 postman工具 简单介绍,这个工具无论是开发还是测试,使用来调试接口的…

    数据库 2023年6月6日
    0159
  • 面试连环炮系列(二十八):数据库读写分离的目的是什么?

    1. 数据库读写分离的目的是什么? 通常,商业系统读得更多,写得更少。读写分离将读写操作分散到不同的节点,可以小幅提升写性能,大幅提升读性能。通常在数据库中采用一主多从的方式,主数…

    数据库 2023年5月24日
    0144
  • python中组合数据的操作

    2022-09-26 组合数据类型: 拷贝: deep(深拷贝) shallow(浅拷贝) 区别:例如,文件中有一个指针指向另一块存储空间,如果是深拷贝则将指向的那一块文件内容也全…

    数据库 2023年6月14日
    0125
  • Centos7下Oracle启动命令

    1、查询挂载历史记录 在root账户下使用一下命令 查看历史使用挂载的那个磁盘 &#x67E5;&#x770B;&#x6302;&#x8F7D;&a…

    数据库 2023年6月16日
    0124
  • mysql入门到精通学习教程,浅谈MySQL是什么?

    Original: https://www.cnblogs.com/chaichaichai/p/15304638.htmlAuthor: 牛仔码农Title: mysql入门到精…

    数据库 2023年5月24日
    0112
  • 学会使用MySQL的Explain执行计划,SQL性能调优从此不再困难

    上篇文章讲了MySQL架构体系,了解到MySQL Server端的优化器可以生成Explain执行计划,而执行计划可以帮助我们分析SQL语句性能瓶颈,优化SQL查询逻辑,今天就一块…

    数据库 2023年5月24日
    0117
  • 中文技术文档写作规范

    使用 markdown 格式书写文档 只使用一二三级标题,三级标题下面的并列性内容使用列表展示 二级标题前使用行分隔符表示分隔 段落之间使用一个空行隔开 一句话或者以逗号分隔的句子…

    数据库 2023年6月6日
    0125
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球