首页 > 其他分享 >Golang 协程配合管道

Golang 协程配合管道

时间:2024-01-02 12:31:58浏览次数:27  
标签:writeData 读取 写入 死锁 Golang 管道 协程


请完成goroutine和channel协同工作的案例,具体要求:
(1)开启一个writeData协程,向管道mtChan中写入50个整数.
(2)开启一个readData协程,从管道intChan中读取writeData写入的数据。
(3)注意:writeData和readDate操作的是同一个管道
(4)主线程需要等待writeData和readDate协程都完成工作才能退出(如果主线程不做处理,那么其他线程还没干完活就直接跑路了)

管道是引用类型,那么写入读取的都是同一个管道,也就是在不同函数不同栈里面读取的都是同一个管道。两个协程同时的向管道里面写入读取数据,而不是一个写完另外一个协程再去读取。

Golang 协程配合管道_死锁

package main

import (
	"fmt"
)

func writeData(initChan chan int) {
	for i := 0; i <= 50; i++ {
		//放入数据
		initChan <- i
		fmt.Println("write data:", i)
	}
	close(initChan)
}
func readData(initChan chan int, exitChan chan bool) {
	//即使管道close之后并不影响读取,当在管道当中取不到数据才会退出
	for {
		//在从一个管道里面读取会返回两个值,ok是有没有正确读取到
		v, ok := <-initChan
		if !ok {
			break
		}
		fmt.Println("read data:", v)
	}
	//readData任务完成之后
	exitChan <- true
	close(exitChan)
}

func main() {
	//创建两个管道
	initChan := make(chan int, 50)
	exitChan := make(chan bool, 1)

	go writeData(initChan)
	go readData(initChan, exitChan)

	for {
		_, ok := <-exitChan
		fmt.Println("ok=", ok)
		if ok {
			break
		}
	}
}

如果给的容量就是50,那么循环50次就刚好放进去了。如果管道和放进去的数据量不匹配,管道的容量小于放进去的数据,又不取出来,那么它就会阻塞,就会死锁。

这个管道可以容纳的数据量很小,要写的数据量很大,只要一边在写,另外一边在读是无所谓的。

如果写的快,读取的慢。那么在写的时候就会阻塞,编译器会发现虽然阻塞了,但是有另外一个协程在往里面读取数据,这样就不会发生死锁。

func producer(ch chan int) {
	i := 0
	for {
		ch <- i
		i++
	}
}

func main() {
	ch := make(chan int, 2)
	go producer(ch)

	for {
		fmt.Println(<-ch)
		time.Sleep(time.Second * 2)
	}
}

0
1
2
3
4
5
6
7

进程 已完成,退出代码为 -1073741510 (0xC000013A: interrupted by Ctrl+C)

死锁编译器底层会分析,如果发现一个地方在不停的写,但是没有任何一个协程去读取这样就直接死锁,如果有一个协程在慢慢的读取这样不会死锁。和写入读取速度没有关系,但是必须有写入的协程和读取的协程。简而言之就是管道需要不停的流动。

Golang 协程配合管道_数据_02

标签:writeData,读取,写入,死锁,Golang,管道,协程
From: https://blog.51cto.com/u_14035463/9067685

相关文章

  • 管道进行进程间通信(上)
    管道进行进程间通信在posix和systemV标准还没有出现的时候,进程间是如何进行通信的呢?这就要借助于我们今天学习的这个东西了。在进程间通信的标准没有出现之前,在os中就已经存在了文件了。而管道就是基于文件的一种进行进程间通信的方式。什么是管道首先一个文件是可以被一个进程打......
  • linux 中 paste、cat 结合管道符合并方向调整
     001、paste[root@pc1test1]#lsa.txtb.txt[root@pc1test1]#cata.txt##测试文件01020304050607080910[root@pc1test1]#catb.txt##测试文件12[root@pc1test1]#cut......
  • Pachyderm: 数据管道的未来
    1.背景介绍Pachyderm是一种开源的数据管道平台,它可以帮助数据科学家和工程师更有效地管理和处理大规模数据。Pachyderm的核心功能是提供一个可扩展的数据管道系统,可以轻松地构建、部署和管理数据处理流程。Pachyderm的设计灵感来自于ApacheHadoop和Docker等开源技术。它将......
  • Golang学习笔记(三)—— 常见控制结构
    Golang常见控制结构条件语句if语句*不支持三目运算符*可省略条件表达式括号*代码块左括号必须在条件表达式尾部*else或elseif必须和上一代码块右括号同一行if条件表达式1{...}elseif条件表达式2{...}else{...}if语法 ......
  • Codeforces Round 918 (Div. 4) (前缀和,权值树状数组,二维偏序, python + golang)
    Dashboard-CodeforcesRound918(Div.4)-Codeforces  fromcollectionsimport*defsolve():a,b,c=list(map(int,input().split()))hs=defaultdict(int)hs[a]+=1hs[b]+=1hs[c]+=1foriinhs:ifhs[i]=......
  • Golang 不使用官方基于cgo的sqlite驱动
    参考以下的代码:packagedatabaseimport( "Forensics_Equipment_Plugin_Manager/logger" "Forensics_Equipment_Plugin_Manager/model" "github.com/glebarez/sqlite" "gorm.io/gorm")varSqliteConn*gorm.DBfuncinit(){ I......
  • Golang开发环境搭建-Vim篇
    本文于2017年3月份完成,发布在个人博客网站上。考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来。最近在研究docker的使用方法,恰好手边有一本docker源码分析的书,所以在ubuntu环境下准备了一套golang的开发环境,便于在学习docker使用的时候顺便学习gol......
  • 关于python3多线程和协程
    以下内容部分由chatgpt生成,本文仅作为备忘和记录。asyncio.sleep和time.sleep都是用于在Python中进行延迟操作的函数,但它们的工作方式和使用场景有一些不同。asyncio.sleep:asyncio.sleep是用于在异步代码中进行暂停的函数,它是asyncio模块中的一部分。在异步程序中......
  • vscode的ssh连接报错过程试图写入的管道不存在
    报错[15:38:48.548]Runningscriptwithconnectioncommand:"C:\Windows\System32\OpenSSH\ssh.exe"-T-D11892"nvidia@nvidia"bash[15:38:48.569]Terminalshellpath:C:\Windows\System32\cmd.exe[15:38:53.152]>ssh:Couldnot......
  • Golang - sync.Pool底层源码详解
    sync.Pool是sync包下的一个组件,用来提高对象复用几率,减少gc的压力,减少内存分配,它是并发安全的,常用来存储并复用临时对象。任何存放区其中的值可以在任何时候被删除而不通知,在高负载下可以动态的扩容,在不活跃时对象池会收缩。可伸缩的,其大小仅受限于内存的大小,可以被看作是一......