对Goroutines

时间:2018-03-27 09:41:00

标签: go concurrency channels

我正在学习Go中的频道和并发性,我对以下代码如何工作感到困惑。

package main

import (
    "fmt"
    "time"
    "sync/atomic"
)

var workerID int64
var publisherID int64

func main() {
    input := make(chan string)
    go workerProcess(input)
    go workerProcess(input)
    go workerProcess(input)
    go publisher(input)
    go publisher(input)
    go publisher(input)
    go publisher(input)
    time.Sleep(1 * time.Millisecond)
}

// publisher pushes data into a channel
func publisher(out chan string) {
    atomic.AddInt64(&publisherID, 1)
    thisID := atomic.LoadInt64(&publisherID)
    dataID := 0
    for {
        dataID++
        fmt.Printf("publisher %d is pushing data\n", thisID)
        data := fmt.Sprintf("Data from publisher %d. Data %d", thisID, dataID)
        out <- data
    }
}

func workerProcess(in <-chan string) {
    atomic.AddInt64(&workerID, 1)
    thisID := atomic.LoadInt64(&workerID)
    for {
        fmt.Printf("%d: waiting for input...\n", thisID)
        input := <-in
        fmt.Printf("%d: input is: %s\n", thisID, input)
    }
}

这是我理解的,如果我错了,请纠正我:

workerProcess Goroutine:

  1. 输入频道作为参数,在频道中指定为
  2. 在for循环中,执行第一个printf。
  3. 通道中的值被分配给变量 input
  4. 执行最后一个printf以显示thisID和input的值。(直到其他Goroutines运行之后,它才真正执行)。
  5. 发布商Goroutine:

    1. 输入频道作为参数,被指定为 out 频道。
    2. 在for循环中,dataID递增,然后执行第一次printf。

    3. 该字符串已分配给数据。

    4. 将数据的值传递给out。

    5. 问题:

      1. out 的值在发布商Goroutine中传递到哪里?它似乎只是在for循环的范围内,不会导致死锁。由于这是一个无缓冲的通道。

      2. 我不知道workerProcess如何从发布者那里获取数据 主要的所有Goroutines都将参数作为通道输入

        如果输出一个函数,我过去常常编写这样的代码 用于另一个:

        foo = fcn1(input) fcn2(foo)

      3. 我怀疑它与Goroutines如何在后台运行有关,但我不确定我会欣赏一个解释。

        1. 为什么没有执行workerProcess中的最后一个printf语句?我的猜测是频道是空的,所以它正在等待一个值。
        2. 部分输出:

          1: waiting for input...
          publisher 1 is pushing data
          publisher 1 is pushing data
          1: input is: Data from publisher 1. Data 1
          1: waiting for input...
          1: input is: Data from publisher 1. Data 2
          1: waiting for input...
          publisher 1 is pushing data
          publisher 1 is pushing data
          publisher 2 is pushing data
          2: waiting for input..
          

1 个答案:

答案 0 :(得分:3)

您有一个频道,它在主屏幕中使用make制作。

此单个频道在workerProcess中名为in,在发布商中名为out。 out是发布者的函数参数,它回答问题1。

问题2:这是频道的整个目的。你输入端输入通道的是输出端。如果一个函数引用了这样一个通道的(一端),它可以与参考同一个通道(它的另一端)的其他人通信。 workerIrocess 收到接收的生产者发送的内容。此发送接收是通过Go上的特殊运算符<-完成的。事实上你的解释有些不对。

out <- data获取数据并通过名为out的通道发送数据,直到<- in从通道读取数据(记住来自main的相同通道的进出名称)。这就是workerProcess和发布者之间的沟通方式。

问题3是重复的。一旦完成,你的整个程序就会终止(在你的情况下,1毫秒后。程序终止后没有任何反应。给程序更多的时间执行。(非打印与通道无关)。