欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【go每日一题】 无缓冲chan作为锁,多协程顺序打印数字

【go每日一题】 无缓冲chan作为锁,多协程顺序打印数字

2025/1/4 11:58:45 来源:https://blog.csdn.net/YiGeiGiaoGiao/article/details/144235313  浏览:    关键词:【go每日一题】 无缓冲chan作为锁,多协程顺序打印数字

问题

多协程顺序打印 1-20数字

解决方案

package testimport ("context""fmt""sync""testing""time"
)/**
多线程打印1-20并要求顺序
*/func Print(ctx context.Context, ch chan int, id int) error {for {select {case <-ctx.Done():fmt.Println("ctx 超时")return ctx.Err()default:num := <-chfmt.Printf("worker: %d, print num: %d\n", id, num)if num == 20 {close(ch)return nil}ch <- num + 1}}}func TestPrintNum(t *testing.T) {ch := make(chan int)ctx, cancelFun := context.WithTimeout(context.Background(), time.Second*3)defer func() {cancelFun()close(ch)}()for i := 0; i < 4; i++ {go Print(ctx, ch, i)}ch <- 1select {case <-ctx.Done():returncase <-time.After(time.Second * 5):return}}func TestAnotherSolution(t *testing.T) {//仅仅把无缓冲的channel当成一把锁使用wg := sync.WaitGroup{}wg.Add(2)ch := make(chan int)go func() {defer wg.Done()// 如果channel中没有数据,<-ch阻塞,直到channel中有一个数据时,取出channel的数据并判断i的值是否是偶数,如果是偶数,则打印for i := 1; i < 10; i += 1 {<-chif i%2 == 0 {fmt.Println(i)}}}()// 第一次循环时,channel为空,可以向channel写入数据,此时i=1,所以,可以打印出1// 第二次循环时,channel不为空,所以 ch <- 0语句阻塞,直到channel内没有数据go func() {defer wg.Done()for i := 1; i < 10; i += 1 {ch <- 0if i%2 == 1 {fmt.Println(i)}}}()wg.Wait()}

扩展

如果将题目变为:多协程,顺序打印1-20,每个协程需要轮流打印呢?

其实这样的题目没什么实际意义,如果要多协程竞争锁打印数字,还要顺序,那还不如一个协程把所有事情处理完毕,多协程一般用来做并行操作

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com