用3个go协程交替打印n到m

这篇具有很好参考价值的文章主要介绍了用3个go协程交替打印n到m。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解题思路:

  1. 创建一个包含三个通道的通道队列 chanQueue,用于协程之间的通信。
  2. 定义一个计数器变量 result,用于跟踪当前打印的数字。
  3. 创建一个退出信号通道 exitChan,用于通知主函数所有协程已完成任务。
  4. 初始化通道队列 chanQueue,并将最后一个通道中的数据置为非零值,以启动第一个协程。
  5. 启动三个协程,每个协程负责打印数字和发送通道信号给下一个协程。
  6. 在每个协程中,使用无限循环来等待上一个协程的通道信号。
  7. 如果计数器变量 result 大于等于 10,说明已经打印完 1 到 10,发送退出信号到 exitChan
  8. 在每个协程中打印当前数字并递增计数器变量 result,然后发送通道信号给下一个协程。
  9. 主函数等待退出信号 exitChan,确保所有协程都已完成任务。
  10. 打印 "done" 表示程序执行完成。

通过使用三个通道和协程之间的同步,每个协程在等待上一个协程的通道信号时,其他协程会被阻塞,从而实现了交替打印数字的效果。

sync.WaitGroup 用于等待三个 goroutine 完成任务,sync.Mutex 用于保护共享资源的并发访问。wg.Done()mutex.Lock() 分别是对应方法的调用,用于减少计数器和获取互斥锁。

sync 包是 Go 语言提供的用于同步和并发控制的包。它提供了一些常用的同步原语,用于在多个 goroutine 之间进行协调和通信。

  • sync.WaitGroup 是一个计数器,用于等待一组 goroutine 完成任务。通过调用 Add() 方法增加计数器的值,调用 Done() 方法减少计数器的值,调用 Wait() 方法阻塞直到计数器的值归零。

  • sync.Mutex 是一个互斥锁,用于保护共享资源的并发访问。通过调用 Lock() 方法获取锁,调用 Unlock() 方法释放锁,确保同一时间只有一个 goroutine 可以访问被保护的代码块。

  • wg.Done() 是一个 WaitGroup 的方法,用于减少计数器的值。在每个 goroutine 完成任务后,调用 Done() 方法通知 WaitGroup 计数器减一。

  • mutex.Lock() 是一个互斥锁的方法,用于获取锁。在访问共享资源之前,调用 Lock() 方法锁定互斥锁,确保只有一个 goroutine 可以访问被保护的代码块。

  • wg.Wait() 是一个 WaitGroup 的方法,用于阻塞直到计数器的值归零。在调用 Wait() 方法之后,程序会等待所有 goroutine 完成任务,然后才继续执行。文章来源地址https://www.toymoban.com/news/detail-542013.html

package main

import (
	"fmt"
)

func main() {
	chanNum := 3 // 定义通道数量为3

	// 创建通道队列切片
	chanQueue := make([]chan struct{}, chanNum)

	var result = 0 // 定义计数器变量
	exitChan := make(chan struct{}) // 创建退出信号通道

	// 初始化通道队列
	for i := 0; i < chanNum; i++ {
		chanQueue[i] = make(chan struct{}) // 创建每个通道
		if i == chanNum-1 {
			go func(i int) {
				chanQueue[i] <- struct{}{} // 启动最后一个协程,发送通道信号
			}(i)
		}
	}

	// 启动三个协程
	for i := 0; i < chanNum; i++ {
		var lastChan, curChan chan struct{}
		if i == 0 {
			lastChan = chanQueue[chanNum-1] // 获取上一个协程的通道
		} else {
			lastChan = chanQueue[i-1]
		}
		curChan = chanQueue[i] // 获取当前协程的通道

		go func(i byte, lastChan, curChan chan struct{}) {
			for {
				<-lastChan // 等待上一个协程的通道信号
				if result >= 10 {
					exitChan <- struct{}{} // 如果已经打印完 1-10,则发送退出信号
					return
				}
				result++
				fmt.Println(result)     // 打印数字
				curChan <- struct{}{} // 发送通道信号给下一个协程
			}
		}('A'+byte(i), lastChan, curChan)
	}

	<-exitChan // 等待退出信号
	fmt.Println("done") // 打印 "done"
}

到了这里,关于用3个go协程交替打印n到m的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Go语言入门12(协程 goroutine)

    进程 ​当运行一个应用程序的时候,操作系统会为这个应用程序启动一个进程。可以将这个进程看作一个包含了应用程序在运行中需要用到和维护的各种资源的容器。这些资源包括但不限于内存地址空间、文件和设备的句柄以及线程 线程 ​一个线程是一个执行空间,这个空

    2023年04月26日
    浏览(39)
  • Go语言中,如何做到数据按类别分发给特定的协程处理

    在 Go 语言中,如果你想按类别将数据分配给特定的协程(goroutine)进行处理,可以使用几种策略。下面我将提供一些方法和示例,说明如何根据数据类别将任务分配给不同的协程来处理。 使用通道(Channel)分发数据 使用映射函数和协程池 使用单一分发器(Dispatcher) 方法

    2024年04月28日
    浏览(27)
  • Go语言-无限可能的管道协程:解锁并发编程的新境界

    在Go语言中,协程(Goroutine)是一种轻量级的并发执行单位,它可以与其他协程并发执行,但不同于操作系统级别的线程。Go语言的协程由Go运行时(Go runtime)来调度,可以在相同的地址空间中并发执行,并且具有非常小的切换开销。 以下是一些关于Go协程的重要特点和用法:

    2024年01月24日
    浏览(41)
  • Java开发者的Golang进修指南:从0->1带你实现协程池

    在Java编程中,为了降低开销和优化程序的效率,我们常常使用线程池来管理线程的创建和销毁,并尽量复用已创建的对象。这样做不仅可以提高程序的运行效率,还能减少垃圾回收器对对象的回收次数。 在Golang中,我们知道协程(goroutine)由于其体积小且效率高,在高并发

    2024年01月22日
    浏览(50)
  • 【算法】两个线程交替打印0~100的数

    总结:条件变量相比于条件判断更加繁琐,但是使用条件变量对于CPU的占用更低,如果是执行更繁杂的多线程任务,使用条件变量效率更高。

    2024年02月14日
    浏览(32)
  • Go语言打印堆栈errors包

    因为Go语言提供的错误太简单了,以至于简单的我们无法更好的处理问题,甚至不能为我们处理错误,提供更有 用的信息,所以诞生了很多对错误处理的库, github.com/pkg/errors 是比较简洁的一样,并且功能非常强大, 受到了大量开发者的欢迎,使用者很多。 跟踪堆栈信息的函

    2024年02月12日
    浏览(40)
  • Golang:Go语言结构

    在我们开始学习 Go 编程语言的基础构建模块前,让我们先来了解 Go 语言最简单程序的结构。 Go 语言的基础组成有以下几个部分: 包声明 引入包 函数 变量 语句 表达式 注释 接下来让我们来看下简单的代码,该代码输出了\\\"Hello World!\\\": 让我们来看下以上程序的各个部分: 第一

    2024年02月10日
    浏览(57)
  • 【Java多线程】交替打印奇偶数

    需求 使用一个线程对一个数进行循环自增,并且使用另外两个线程对当前的数进行打印,一个线程打印奇数,一个线程打印偶数,要求最终输出结果必须按顺序打印出来 代码 先定义全局变量 指定三个线程: 线程一:对一个整型数(i50)进行递增 线程二:打印奇数; 线程三

    2024年02月10日
    浏览(40)
  • golang实现webgis后端开发

    目录 前言 二、实现步骤 1.postgis数据库和model的绑定 2.将pg库中的要素转换为geojson (1)几何定义 (2)将wkb解析为几何类型 (3)定义geojson类型 (4)数据转换 (5)数据返回  2.前端传入的geojson储存到数据库 3、其他功能实现 总结         停更了接近一个月都在研究一门新语言gola

    2024年02月08日
    浏览(49)
  • Go语言入门记录:从基础到变量、函数、控制语句、包引用、interface、panic、go协程、Channel、sync下的waitGroup和Once等

    程序入口文件的包名必须是main,但主程序文件所在文件夹名称不必须是 main ,即我们下图 hello_world.go 在 main 中,所以感觉 package main 写顺理成章,但是如果我们把 main 目录名称改成随便的名字如 filename 也是可以运行的,所以迷思就在于写在文件开头的那个 package main 和 java

    2024年02月11日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包