关于goroutine并发的问题

huangapple go评论82阅读模式
英文:

Trouble about goroutine concurrent

问题

我遇到了关于goroutine并发的一些问题。按照我的期望,它应该是异步运行并几乎同时打印输出,但实际上它是在等待后才运行。

以下是你的测试代码:

package main

type batchD []string
var cBD = make(chan batchD, 6)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())

    data := [][]string{}
    data = append(data, []string{"71", "40348270", "6", "win888e", "6", "1", "N", "127.0.0.1"})
    data = append(data, []string{"71", "40348270", "6", "win888e", "6", "1", "N", "127.0.0.1"})
    data = append(data, []string{"71", "40348270", "6", "win888e", "6", "1", "N", "127.0.0.1"})
    data = append(data, []string{"71", "129499244", "6", "win888e", "6", "1", "N", "127.0.0.1"})
    data = append(data, []string{"71", "40348270", "6", "win888e", "6", "1", "N", "127.0.0.1"})
    data = append(data, []string{"71", "40348270", "6", "win888e", "6", "1", "N", "127.0.0.1"})

    for k,v := range data {
        go func() {
            fmt.Println(k,v)
            //batchD{}.BatchDeposit(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
            delay()
            cBD <- data[k]
        }()
        <-cBD
    }
}

func delay() {
    time.Sleep(1 * time.Second)
    t := Basic.NowTime("Taipei")
    fmt.Println(t)
}

你得到的输出是:

0 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
1 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:41
2 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:42
3 [71 129499244 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:43
4 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:44
5 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:45

你期望的输出是:

0 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
1 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
2 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
3 [71 129499244 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
4 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40
5 [71 40348270 6 win888e 6 1 N 127.0.0.1]
2017-08-16 12:00:40

如果你有任何建议或提示,都会很有帮助。谢谢!

英文:

I got some trouble about goroutine concurrent. In my expect, it should run asynchronously and print out almost at same time but what it really did was running with waiting

MyTestCode

package main

type batchD []string
var cBD = make(chan batchD, 6)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	data := [][]string{}
	data = append(data, []string{&quot;71&quot;, &quot;40348270&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})
	data = append(data, []string{&quot;71&quot;, &quot;40348270&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})
	data = append(data, []string{&quot;71&quot;, &quot;40348270&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})
	data = append(data, []string{&quot;71&quot;, &quot;129499244&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})
	data = append(data, []string{&quot;71&quot;, &quot;40348270&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})
	data = append(data, []string{&quot;71&quot;, &quot;40348270&quot;, &quot;6&quot;, &quot;win888e&quot;, &quot;6&quot;, &quot;1&quot;, &quot;N&quot;, &quot;127.0.0.1&quot;})

	for k,v := range data {
		go func() {
			fmt.Println(k,v)
			//batchD{}.BatchDeposit(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7])
			delay()
			cBD &lt;- data[k]
		}()
		&lt;-cBD
	}
}

func delay() {
	time.Sleep(1 * time.Second)
    t := Basic.NowTime(&quot;Taipei&quot;)
	fmt.Println(t)
}

Output I got

0 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
1 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:41  
2 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:42  
3 [71 129499244 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:43  
4 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:44  
5 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:45  

Output I Expected

0 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
1 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
2 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
3 [71 129499244 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
4 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  
5 [71 40348270 6 win888e 6 1 N 127.0.0.1]  
2017-08-16 12:00:40  

Any suggestions or tips will helps. Thanks.

答案1

得分: 2

基本上,你有:

var cBD = make(chan batchD, 6)
for k := range data {
	go func() {
		time.Sleep(1 * time.Second)
		fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
		cBD <- data[k]
	}()
	<-cBD
}

每次循环都会启动一个 goroutine。然后,通过通道接收 <-cBD,循环会等待,直到 goroutine 在一秒钟后通过 cBD <- data[k] 发送到通道中。例如,

2017-08-16 02:52:46
2017-08-16 02:52:47
2017-08-16 02:52:48
2017-08-16 02:52:49
2017-08-16 02:52:50
2017-08-16 02:52:51
英文:

Essentially, you have:

var cBD = make(chan batchD, 6)
for k := range data {
	go func() {
		time.Sleep(1 * time.Second)
		fmt.Println(time.Now().Format(&quot;2006-01-02 15:04:05&quot;))
		cBD &lt;- data[k]
	}()
	&lt;-cBD
}

Each loop starts a goroutine. The loop then waits, via the channel receive &lt;-cBD, until the goroutine sends to the channel, via cBD &lt;- data[k], one second later. For example,

2017-08-16 02:52:46
2017-08-16 02:52:47
2017-08-16 02:52:48
2017-08-16 02:52:49
2017-08-16 02:52:50
2017-08-16 02:52:51

huangapple
  • 本文由 发表于 2017年8月16日 12:15:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/45705032.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定