golang 协程题目

都是一个货色,要么使用无缓冲channel, 要么使用有缓冲chan+waitgroup等待协程退出,或者使用全局变量判断是否终止协程

2个协程交替打印奇数和偶数

无缓冲channel实现

go 复制代码
package main

import "fmt"

func main() {

	maxval := 10
	ch1 := make(chan struct{})
	ch2 := make(chan struct{})
	close := make(chan struct{})
	go func() {
		for i := 1; i <= maxval ; i++ {
			if i%2 == 1 {
				<-ch1
				fmt.Printf("%d\n", i)
				ch2 <- struct{}{}
			}
		}
	}()
	go func() {
		for i := 1; i <= maxval ; i++ {
			if i%2 == 0 {
				<-ch2
				fmt.Printf("%d\n", i)

				if i == maxval {
					close <- struct{}{}
				} else {
					ch1 <- struct{}{}
				}
			}
		}
	}()

	ch1 <- struct{}{}
	<-close
}

有缓冲channel实现

go 复制代码
package main

import "fmt"

func main() {

	maxval := 10
	ch1 := make(chan struct{}, 1)
	ch2 := make(chan struct{}, 1)
	close := make(chan struct{})
	go func() {
		for i := 1; i <= maxval; i++ {
			if i%2 == 1 {
				<-ch1
				fmt.Printf("%d\n", i)
				ch2 <- struct{}{}
			}
		}
	}()
	go func() {
		for i := 1; i <= maxval; i++ {
			if i%2 == 0 {
				<-ch2
				fmt.Printf("%d\n", i)
				ch1 <- struct{}{}
			}
		}
		close <- struct{}{}
	}()

	ch1 <- struct{}{}
	<-close
}

有缓冲channel+ waitgroup

go 复制代码
package main

import (
	"fmt"
	"sync"
)

func main() {

	maxval := 10
	ch1 := make(chan struct{}, 1)
	ch2 := make(chan struct{}, 1)
	wg := &sync.WaitGroup{}
	wg.Add(2)
	go func() {
		defer wg.Done()
		for i := 1; i <= maxval; i++ {
			if i%2 == 1 {
				<-ch1
				fmt.Printf("%d\n", i)
				ch2 <- struct{}{}
			}
		}
	}()
	go func() {
		defer wg.Done()
		for i := 1; i <= maxval; i++ {
			if i%2 == 0 {
				<-ch2
				fmt.Printf("%d\n", i)
				ch1 <- struct{}{}
			}
		}
	}()

	ch1 <- struct{}{}
	wg.Wait()
}

N个协程交替打印1到maxVal

go 复制代码
package main

import (
	"fmt"
)

func main() {

	cur := 0
	maxval := 10
	N := 3
	chs := make([]chan struct{}, 3)
	closeCh := make(chan struct{})

	for i := 0; i < N; i++ {
		chs[i] = make(chan struct{})
	}
	for i := 0; i < N; i++ {
		go func(i int) {
			for {
				_, ok := <-chs[i]
				if !ok {
					//fmt.Printf("go %d close\n", i)
					return
				}

				fmt.Printf("go %d print %d\n", i, cur)
				if cur == maxval {
					closeCh <- struct{}{}
					return
				}
				cur++
				chs[(i+1)%N] <- struct{}{}
			}
		}(i)
	}

	chs[0] <- struct{}{}
	<-closeCh
	for i := 0; i < N; i++ {
		close(chs[i])
	}
	fmt.Printf("main end\n")
}

使用三个协程分别打印A,B,C打印这个100次

go 复制代码
package main

import (
	"fmt"
)

func main() {

	cnt := 2
	N := 3
	chs := make([]chan struct{}, 3)
	closeCh := make(chan struct{})

	for i := 0; i < N; i++ {
		chs[i] = make(chan struct{}, 1)
	}
	for i := 0; i < N; i++ {
		go func(i int) {
			b := byte('A') + byte(i)
			for j := 0; j < cnt; j++ {
				<-chs[i]
				fmt.Printf("go %d print %c\n", i, b)
				chs[(i+1)%N] <- struct{}{}
			}
			if i == N-1 {
				closeCh <- struct{}{}
			}
		}(i)
	}

	chs[0] <- struct{}{}
	<-closeCh
	for i := 0; i < N; i++ {
		close(chs[i])
	}
	fmt.Printf("main end\n")
}
相关推荐
Tairitsu_H14 小时前
[C++] C++11右值引用与移动语义揭秘
开发语言·c++·c++11·右值引用·移动语义
麻辣布丁14 小时前
java集合篇面试模拟
java·开发语言·面试
niucloud-admin14 小时前
JAVA V6 多商户商城 开发文档——插件开发规范
java·开发语言
海盗123414 小时前
DSH 接入 OpenCode Go 报 400 MissingSessionID:从 LLM 语义层退到 fetch 传输层的完整排障
开发语言·后端·golang
weixin1997010801615 小时前
《Mercari OTA 直连接入:日本二手电商出海的API通道与600次/分钟限流实战》(附Python源码)
开发语言·数据库·python
一木 之林15 小时前
第 3 节 在 AI 行业中,C/C++ 编程中的动态库和静态库
c语言·c++·后端
库玛西15 小时前
深度解构高并发利器:纯事件驱动 Reactor 模式的设计哲学与工程实践
服务器·开发语言·c++·笔记·tcp/ip
skywalkerch15 小时前
Spring 循环依赖与三级缓存
后端
lemon_sjdk15 小时前
JavaScript 常用关键字全解析
开发语言·javascript·ecmascript
linx29515 小时前
单元五 · 对称认知·下:编译与链接
linux·c语言·开发语言·c++·嵌入式硬件