Go并发按顺序打印

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

go concurrency prints serially

问题

我正在尝试并发打印,但无法弄清楚为什么它是串行的,以下是我放置的代码:

package main

import (
	"fmt"
	"sync"
)

func main() {
	fmt.Println("Hello, playground")
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for i := 0; i < 4; i++ {
			if i%2 == 0 {
				fmt.Println("hi", i)
			}
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i < 4; i++ {
			if i%2 != 0 {
				fmt.Println("g", i)
			}
		}
		wg.Done()
	}()
	wg.Wait()
}

期望输出是:
hi0
g1
hi2
g3

但我得到的输出是:
from g 1
from g 3
hi 0
hi 2

英文:

i am trying to print concurrently but not able to figure out why its serial, have put the code below

package main

import (
        &quot;fmt&quot;
        &quot;sync&quot;
)

func main() {
        fmt.Println(&quot;Hello, playground&quot;)
        var wg sync.WaitGroup
        wg.Add(2)
    go func(){
        for i := 0; i &lt; 4; i++ {
                if i%2 == 0 {
                        fmt.Println(&quot;hi&quot;, i)
                }
        }
         wg.Done()
       }()
        go func() {

                for i := 0; i &lt; 4; i++ {
                        if i%2 != 0 {
                                fmt.Println(&quot;g&quot;, i)
                        }

                }
                wg.Done()
        }()
        wg.Wait()
}

expectation is
hi0
g1
hi2
g3

but i get

from g 1
from g 3
hi 0
hi 2

答案1

得分: 3

这样一个小函数很少能展示并发性,因为第一个goroutine可能在第二个goroutine开始之前甚至在上下文切换之前就完成了。如果在循环中添加一个小的暂停,你将观察到交错执行的结果:

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for i := 0; i < 4; i++ {
			if i%2 == 0 {
				fmt.Println("hi", i)
			}
			time.Sleep(10 * time.Millisecond)
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i < 4; i++ {
			if i%2 != 0 {
				fmt.Println("from g", i)
			}
			time.Sleep(10 * time.Millisecond)

		}
		wg.Done()
	}()
	wg.Wait()
}
英文:

Such a small function is less likely to demonstrate the concurrency, because the first goroutine may complete even before the second one starts, or before context switch happens. If you add a small pause to the loop, you will observe the interleaving:

package main

import (
	&quot;fmt&quot;
	&quot;sync&quot;
	&quot;time&quot;
)

func main() {
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		for i := 0; i &lt; 4; i++ {
			if i%2 == 0 {
				fmt.Println(&quot;hi&quot;, i)
			}
			time.Sleep(10 * time.Millisecond)
		}
		wg.Done()
	}()
	go func() {
		for i := 0; i &lt; 4; i++ {
			if i%2 != 0 {
				fmt.Println(&quot;from g&quot;, i)
			}
			time.Sleep(10 * time.Millisecond)

		}
		wg.Done()
	}()
	wg.Wait()
}

huangapple
  • 本文由 发表于 2021年9月24日 17:06:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/69312370.html
匿名

发表评论

匿名网友

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

确定