交替打印 1-100 之间的奇数和偶数
10月 2, 2021
题目:两个 goroutine 交替打印1-100之间的奇数和偶数。
方法一 #
利用非缓冲 channel 的阻塞。
package main
import (
"fmt"
"sync"
)
func main() {
ch := make(chan struct{})
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
for i := 1; i < 101; i++ {
ch <- struct{}{}
//奇数
if i%2 == 1 {
fmt.Println("线程1打印:",i)
}
}
}()
go func() {
defer wg.Done()
for i := 1; i < 101; i++ {
<- ch
//偶数
if i%2 == 0 {
fmt.Println("线程2打印:",i)
}
}
}()
wg.Wait()
}
方法二 #
和方法一类似,但省去了 if 判断。
package main
import (
"fmt"
"sync"
)
var ch = make(chan struct{})
var wg sync.WaitGroup
func go1() {
defer wg.Done()
for i := 1; i <= 10; i += 2 {
fmt.Println(i)
ch <- struct{}{}//不能与上一行交换位置
<- ch
}
}
func go2() {
defer wg.Done()
for i := 2; i <= 10; i += 2 {
<- ch
fmt.Println(i)
ch <- struct{}{}
}
}
func main() {
wg.Add(2)
go go1()
go go2()
wg.Wait()
}
方法三 #
使用 runtime.Gosched
方法实现。
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
//设置可同时使用的CPU核数为1
var wg sync.WaitGroup
runtime.GOMAXPROCS(1)
wg.Add(2)
go func() {
defer wg.Done()
for i := 1; i < 101; i++ {
//奇数
if i%2 == 1 {
fmt.Println("线程1打印:",i)
}
//让出cpu
runtime.Gosched()
}
}()
go func() {
defer wg.Done()
for i := 1; i < 101; i++ {
//偶数
if i%2 == 0 {
fmt.Println("线程2打印:",i)
}
//让出cpu
runtime.Gosched()
}
}()
wg.Wait()
}
进阶问题:使用 N 个 Goroutine 打印 #
package main
import (
"fmt"
"sync"
)
var ch1, ch2 = make(chan struct{}), make(chan struct{})
var wg sync.WaitGroup
func go1() {
defer wg.Done()
for i := 1; i <= 10; i += 2 {
<- ch1
fmt.Println(i)
ch2 <- struct{}{}
}
<- ch1
}
func go2() {
defer wg.Done()
for i := 2; i <= 10; i += 2 {
<- ch2
fmt.Println(i)
ch1 <- struct{}{}
}
}
func main() {
wg.Add(2)
go go1()
go go2()
ch1 <- struct{}{}
wg.Wait()
}