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)

大家都在看

  • 记一次配置Linux服务器配置ssh登陆方式

    测试系统信息: 1.在目标机器中添加文件 vi /root/.ssh/authorized_keys //创建文件authorized_keys, 需要使用哪个用户登录,就在对应的…

    数据库 2023年6月11日
    088
  • 线程池执行流程图

    public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeU…

    数据库 2023年6月16日
    0132
  • Gorm 的黑魔法

    开发过程中,看到同事的代码写了这么一段: db = db.Session(&gorm.Session{Context: db.Statement.Context}).Fir…

    数据库 2023年6月9日
    098
  • 2018年最新JAVA面试题总结之数据库(3)

    转自于:https://zhuanlan.zhihu.com/p/39804394 1、MySQL的delete与truncate区别? 回答:delete语句执行删除的过程是每次…

    数据库 2023年6月16日
    090
  • MySQL(一)——查看密码与修改

    查看数据库密码,策略与修改 RPM安装: 源码安装: 进入:数据库 进入数据库后第一步设置密码: 查看密码策略 修改密码策略,长度 0宽容模式 混合模式,0关闭大小写 特殊字符 O…

    数据库 2023年6月14日
    0122
  • MySQL优化之索引解析

    索引的本质 MySQL索引或者说其他关系型数据库的索引的本质就只有一句话, 以空间换时间。 索引的作用 索引关系型数据库为了 加速对表中行数据检索的( 磁盘存储的) 数据结构 索引…

    数据库 2023年5月24日
    092
  • MySQL 卸载与安装

    MySQL 卸载与安装 以Windows10操作系统为例: 一、 先看看如何卸载 1、首先,停止window的MySQL服务,【windows键+R 】打开运行框,输入【servi…

    数据库 2023年5月24日
    074
  • 前端JavaScript-每日一题

    2022 09 本文来自博客园,作者:吴知木,转载请注明原文链接:https://www.cnblogs.com/zh1q1/p/16726853.html Original: h…

    数据库 2023年6月11日
    093
  • Mongodb使用总结

    Mongodb使用总结 基于内存操作,便于与网站交互 数据库-集合-文档(存储多种数据类型),我们的操作都是基于单文档进行操作,并且通过冗余字段进行操作 嵌入式数组文档减少了对昂贵…

    数据库 2023年6月11日
    086
  • 关于ThreadLocal的一道面试题

    问:上面这段代码会输出什么?为什么? 为什么输出1然后空指针了? 输出1是没有任何问题的。那空指针是为什么呢? 因为这是两个线程,子线程和主线程。子线程设置1,主线程肯定拿不到啊。…

    数据库 2023年6月16日
    0107
  • 【MySQL】笔记(2)— 部分 DQL 语句;条件查询;排序;分组函数;单行处理函数;group by ,having ;

    1.简单的查询语句(DQL): select 字段名1,字段名2,字段名3,…. from 表名; 注意:1、任何一条sql语句都以”;”结尾;…

    数据库 2023年5月24日
    0108
  • 聊斋-河间生

    人的善恶在转瞬之间就可以改变,发现错误时往往已经差之千里了,但是发现错误及时改正这不也是很美好的一件事情么?河间生就是讲了这么一件事情。 主角简介:河间某生,家里比较富裕,烧火用的…

    数据库 2023年6月6日
    0106
  • Spring Security OAuth 笔记

    1 单点登录 关于单点登录的原理,我觉得下面这位老哥讲的比较清楚,有兴趣可以看一下,下面我把其中的重点在此做个笔记总结 https://juejin.cn/post/6844904…

    数据库 2023年6月14日
    083
  • Java 反射学习笔记

    反射,指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法。这种动态获取信息,以及动态调用对象方法的功能,叫做 Java 语言…

    数据库 2023年6月11日
    099
  • day03-MySQL基础知识02

    MySQL基础知识02 4.CRUD 数据库CRUD语句:增(create)、删(delete)、改(update)、查(Retrieve) Insert 语句 (添加数据) Up…

    数据库 2023年6月11日
    080
  • 吃饱年代

    Original: https://www.cnblogs.com/life2refuel/p/15211899.htmlAuthor: 喜欢兰花山丘Title: 吃饱年代

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