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")
}
相关推荐
lly202406几秒前
C# 结构体(Struct)
开发语言
短剑重铸之日6 分钟前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
YMWM_11 分钟前
python3继承使用
开发语言·python
Once_day26 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
喜欢喝果茶.1 小时前
QOverload<参数列表>::of(&函数名)信号槽
开发语言·qt
亓才孓1 小时前
[Class类的应用]反射的理解
开发语言·python
努力学编程呀(๑•ี_เ•ี๑)1 小时前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea
Dragon Wu1 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
island13141 小时前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构任务的 Stream 调度机制
开发语言·人工智能·深度学习·神经网络