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")
}
相关推荐
外收内放2 分钟前
Python基础语法练习题(69)
开发语言·python
lojox6 分钟前
深入理解 C++ STL:vector 底层实现、迭代器失效与 list 特性
开发语言·c++
iotxiaohu9 分钟前
用 cflow 查看 C 函数调用关系
c语言·开发语言·cflow
zhang-ge9 分钟前
python包和项目管理器uv在ubuntu下的安装与使用
开发语言·python·uv
高频因子挖掘机1 小时前
股票分红送转后价格“断层”:前复权、后复权和不复权该怎么选?
后端·github·api
一条泥憨鱼1 小时前
【Redis | 黑马点评】短信登录功能 源码深度分析
java·redis·后端·session·黑马点评
威哥爱编程1 小时前
【AI全栈12-12】Spring Boot 3.x → 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·spring boot·后端
微笑星河q1 小时前
C++类和对象(下)初始化列表、类型转换、static、友元、内部类、匿名对象
开发语言·c++
威哥爱编程1 小时前
【AI全栈12-11】Spring Boot 把 AI 接口真正上线扛量:限流 / 降级 / 可观测
java·spring boot·后端
小蒜学长1 小时前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务