四段代码入门Go协程以及channel!

栏目: Go · 发布时间: 5年前

内容简介:写一个简单的程序,使得一个协程用来向channel中写如数据,一个用来读取数据。然后下面是三段代码,大家看之前可以小思考下运行结果,最好自己动手测试下。当然是阻塞的,写协程阻塞了,读协程只能干等着啊,这个问题好像有点(๑•ᴗ•๑)

写一个简单的程序,使得一个协程用来向channel中写如数据,一个用来读取数据。

import (
    "fmt"
    "strconv"
    "testing"
)
/**
在这个示例中,我们有
  - 一个message作为channel
  - 一个协程用来发送消息
  - 主协程用来接收消息
*/
func Test_message(t *testing.T)  {
    /**
    声明一个长度为 1 的channel
    */
    messages := make(chan string)

    /**
    该协程负责向channel发送数据,共发送五次
    */
    go func() {
        for i := 0; i < 5; i++ {
            messages <- "Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息"
        }
    }()

    /**
    读取channel中的数据,这是个阻塞的操作
    */
    for i := 0; i < 5; i++ {
        fmt.Println(<- messages)
    }
}

代码样例

然后下面是三段代码,大家看之前可以小思考下运行结果,最好自己动手测试下。

假如向channel中写入数据时,设置1秒钟的延迟,那么读取channel数据的协程会阻塞吗?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在这个示例中,我们的副协程在向channel中写入数据的时候,有一秒的延迟

然后我们发现控制台断断续续的打印出了内容

说明我们从channel中读取消息是个阻塞的行为
 */
func Test_message1(t *testing.T)  {
    /**
    声明一个长度为 1 的channel
     */
    messages := make(chan string)

    /**
    该协程每隔一秒向channel发送一个数据
     */
    go func() {
        for i := 0; i < 5; i++ {
            time.Sleep(time.Second * 1)
            messages <- "Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息"
        }
    }()

    /**
    读取channel中的数据,这是个阻塞的操作
     */
    for i := 0; i < 5; i++ {
        fmt.Println(<- messages)
    }
}

当然是阻塞的,写协程阻塞了,读协程只能干等着啊,这个问题好像有点(๑•ᴗ•๑)

如果给读协程设置一秒延迟,那么写协程会阻塞吗?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在这个示例中,我们向channel中读取数据时,设置了一秒的延迟

然后我们发现控制台断断续续的打印出了内容

说明我们向channel中写入消息也是是个阻塞的行为
它受到channel容量的限制,如果channel容量满了,写操作就会阻塞协程
*/
func Test_message2(t *testing.T)  {
    /**
    声明一个长度为一的channel
    */
    messages := make(chan int)

    /**
    该协程每隔一秒向channel发送一个数据
    */
    go func() {
        for i := 0; i < 5; i++ {
            messages <- i
            fmt.Println("Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息")
        }
    }()

    /**
    读取channel中的数据,这是个阻塞的操作
    */
    for i := 0; i < 5; i++ {
        <- messages
        time.Sleep(time.Second * 1)
    }
}

答案是会的,因为channel的容量是有限的,没有消费者的话,生产者是不能继续生产的。

如何给channel设置一个5的容积,那么下面程序的运行结果会是怎么样的?

import (
    "fmt"
    "strconv"
    "testing"
    "time"
)

/**
在这个示例中,我们创建了一个有缓存channel

大家可以自行执行以下,可以看到前面6次打印非常快,后面三次则是断断续续的

这就是有缓冲的channel,即使没有消费者,我们依旧可以向channel中写入数据,
直到容量达到上限
*/
func Test_message3(t *testing.T)  {
    /**
    声明一个容量为5的channel
    */
    messages := make(chan int, 5)

    /**
    该协程持续的尝试向channel中发送一个数据
    */
    go func() {
        for i := 0; i < 10; i++ {
            messages <- i
            fmt.Println("Hello, 这是第 " + strconv.Itoa(i) + " 次传递消息")
        }
    }()

    /**
    每隔一秒读取一次channel中的数据,这是造成channel内元素逐渐累积
    */
    for i := 0; i < 5; i++ {
        <- messages
        time.Sleep(time.Second * 1)
    }
}

答案是前面6次打印非常快,后面三次则是断断续续的

怎么样,是不是对协程和channel有了基本的认识了

https://github.com/fish-bugs/...


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

第二曲线:跨越“S型曲线”的二次增长

第二曲线:跨越“S型曲线”的二次增长

[英]查尔斯·汉迪(Charles Handy) / 苗青 / 机械工业出版社 / 2017-6 / 49.00

S型曲线是每个组织和企业在预测未来时一定会参考的工具,一切事物的发展都逃不开S型曲线(“第一曲线”)。 然而,从公司组织、企业治理、市场的变化,到个人职业发展、社会人际关系以及未来的教育与社会价值,多维度地探讨这个世界需要重新以不同的角度来思考问题,不能够总是停留在“第一曲线”的世界。 如果组织和企业能在第一曲线到达巅峰之前,找到带领企业二次腾飞的“第二曲线”,并且第二曲线必须在第一曲......一起来看看 《第二曲线:跨越“S型曲线”的二次增长》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具