1. 首页
  2. 主题
  3. Go面试题

两个goroutine 循环打印1~10

jxy_90 · · 8284 次点击
今天面试遇到"两个goroutine 循环打印1~100" 思路是一个goroutine放数据,一个goroutine读数据,可是结果却是乱序的 ```golang func Test_0(t *testing.T) { //fmt.Println("123") c1 := make(chan int) wg := sync.WaitGroup{} wg.Add(2) go func() { for i := 0; i < 10; i += 2 { c1 <- 1 fmt.Print(i) } wg.Done() }() go func() { for i := 1; i < 10; i += 2 { <-c1 fmt.Print(i) } wg.Done() }() wg.Wait() } ``` === RUN Test_0 0132457689--- PASS: Test_0 (0.00s) PASS ----------------------------分割线---------------------------------- 之后看了晚上的解答,只是循环的时候从+2->++,奇怪?这样就没问题呢? ```golang func Test_dongchedi(t *testing.T) { //fmt.Println("123") c1 := make(chan int) wg := sync.WaitGroup{} wg.Add(2) go func() { for i := 1; i <= 10; i++ { c1 <- 1 if i%2 == 1 { fmt.Print(i) } } wg.Done() }() go func() { for i := 1; i <= 10; i++ { <-c1 if i%2 == 0 { fmt.Print(i) } } wg.Done() }() //c1 <- 1 wg.Wait() } ``` === RUN Test_dongchedi 12345678910--- PASS: Test_0(0.00s) PASS
```go func Test_pingpang(t *testing.T) { const N = 100 ping := make(chan int, 1) pang := make(chan int, 1) done := make(chan [0]int) pingpang := func(in &lt;-chan int, out chan&lt;- int) { // 根本不需要关心到底是+=1还是+=2 for x := range in { t.Log(x) if x &lt; N { out &lt;- (x + 1) continue } close(done) break } } ping &lt;- 0 // 发球 // 也不需要关心多少goroutine,甚至ping/pang也可以不配对。以下是斗地主3打1 go pingpang(ping, pang) go pingpang(pang, ping) go pingpang(ping, pang) go pingpang(ping, pang) &lt;-done close(ping) close(pang) } ```
#17
更多评论
现在定义上面的协程为 g1 现在定义下面的协程为 g2 你这段逻辑,不管怎么输出,其执行的顺序一定是 g1 g2 g2 g1 g1 g2 g2 g1 ... 按照这个线性逻辑,去和你的输出做匹配,你就会发现问题所在
#1
```golang package main import ( &#34;fmt&#34; &#34;sync&#34; ) func main() { //fmt.Println(&#34;123&#34;) c1 := make(chan int) wg := sync.WaitGroup{} wg.Add(2) go func() { for i := 0; i &lt; 10; i += 2 { fmt.Println(&#34;go1 sending &#34;) c1 &lt;- 1 fmt.Println(&#34;go1 sent # test&#34;) } wg.Done() }() go func() { for i := 0; i &lt; 10; i += 2 { fmt.Println(&#34;go2 receiving &#34;) &lt;-c1 fmt.Println(&#34;go2 received # test&#34;) } wg.Done() }() wg.Wait() } ``` 结果如下 带 # test 就是你打印的那部分 ```bash go2 receiving go1 sending go1 sent # test go1 sending go2 received # test go2 receiving go2 received # test go2 receiving go1 sent # test go1 sending go1 sent # test go1 sending go2 received # test go2 receiving go2 received # test go2 receiving go1 sent # test go1 sending go1 sent # test go2 received # test ``` 可以看到,一旦完成一次 channel 的通信后,如果当前 goroutine 还在占用 processor, 那么就会继续运行,直到下一次阻塞
#2

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中