交替打印 1-100 之间的奇数和偶数

交替打印 1-100 之间的奇数和偶数

10月 2, 2021
Go, Algorithms

题目:两个 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()
}

参考 https://blog.csdn.net/xingyu97/article/details/118116971

本文共 564 字,上次修改于 Jul 9, 2024,以 CC 署名-非商业性使用-禁止演绎 4.0 国际 协议进行许可。

相关文章

» 实现限流的几种方案

» “结点”还是“节点”?

» Go 程序是怎样跑起来的?

» Go 语言的垃圾回收机制概览

» Go 语言的内存管理机制概览