Go语言的并发编程

Go 学习笔记 · 进阶篇 · 第二天:并发编程深度实践 Go 的并发是轻量高效的,Goroutine 比线程香。Channel 是 goroutine 之间的传声筒。WaitGroup、Mutex、Context 是并发控制的三剑客。并发编程容易埋雷,写完一定记得加-race运行!今日咒语:“人生苦短,让 goroutine 去忙,主程序才轻松。 阅读详情

并发指在同一时间内可以执行多个任务。并发编程含义比较广泛,包含多线程编程、多进程编程及分布式程序等。

Go语言里的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为协程(goroutine)时,Go语言会将其视为一个独立的工作单元,这个单元会被调度到可用的逻辑处理器上执行。

并发编程基础

1、并发与并行(理论没看懂)

理解操作系统的线程(thread)和进程(process),有助于理解Go语言运行时调度器如何得用操作系统来并发运行goroutine。

并行是让不同的代码片段同时在不同的物理处理器上执行。并行的关键是同时做很多事情,而并发是指同时管理很多事情,这些事情可能只做了一半就被暂停去做别的事情了。

使用较少的资源做更多的事情,是指导Go语言设计的哲学。

2、指定使用核心数

Go语言默认会调用CPU核心数,这些功能都是自动调整的,但是也提供了相应的标准库来指定核心数。使用flags包可以调整程序运行时调用的CPU核心数。

代码如下:

package main

import (
	"fmt"
	"time"
)

func longWait() {
	fmt.Println("开始longWait()")
	time.Sleep(5 * 1e9)
	fmt.Println("结束longWait()")
}

func shortWait() {
	fmt.Println("开始shortWait()")
	time.Sleep(2 * 1e9)
	fmt.Println("结束shortWait()")
}

func main() {
	fmt.Println("这里是main()开始的地方")
	go longWait()
	go shortWait()
	fmt.Println("挂起main()")
	time.Sleep(10 * 1e9)
	fmt.Println("这里是main()结束的地方")
}

main()、longWait()和shortWait()三个函数作为独立的处理单元按顺序启动,然后开始并行运行,每一个函数都在运行的开始和结束阶段输出了消息。

运行结果如下:

这里是main()开始的地方
挂起main()
开始longWait()
开始shortWait()
结束shortWait()
结束longWait()
这里是main()结束的地方

如果移除go语言关键字同,重新运行程序:

这里是main()开始的地方
开始longWait()
结束longWait()
开始shortWait()
结束shortWait()
挂起main()
这里是main()结束的地方

协程(goroutine)

操作系统自己掌管的进程(process)、进程内的线程(thread)以及进程内的协程(coroutine,也叫轻量级线程)。

协程的最大优势在于其“轻量级”,可以轻松创建上百万个协程而不会导致系统资源衰竭,而线程和进程通常最多也不能超过1万个。

Go语言在语言级别支持轻量级线程,叫goroutine。

1、协程基础

goroutine是Go语言并行设计的核心。

goroutine是通过Go程序的runtime管理的一个线程管理器。goroutine通过go关键字实现了,其实就是一个普通的函数。

代码如下:

package main

import (
	"fmt"
	"runtime"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		runtime.Gosched()
		fmt.Println(s)
	}
}

func main() {
	go say("world")
	say("hello")
}

运行结果如下:与书本不一样。

hello
hello
hello
hello
hello

书本是:

hello
world
hello
world
hello
world
hello
world
hello

并发处理:Go例程,代码如下:

package main

import (
	"fmt"
)

func routine1(index int) {
	for i := 0; i < 10; i++ {
		fmt.Println(index, " : ", i)
	}
}
func main() {
	go routine1(1)
	go routine1(2)
	for i := 0; i < 10; i++ {
		fmt.Println("0: ", i)
	}
}

运行结果如下:(感觉不对,不明白什么意思)

0:  0
0:  1
0:  2
0:  3
0:  4
0:  5
0:  6
0:  7
0:  8
0:  9

2、协程间通信

通常有两种最常见的并发通信模型:共享数据和消息。

代码如下:

package main

import (
	"fmt"
	"runtime"
	"sync"
)

var counter int = 0

func Count(lock *sync.Mutex) {
	lock.Lock()
	counter++
	fmt.Println(z)
	lock.Unlock()
}

func main() {
	lock := &sync.Mutex{}
	for i := 0; i < 10; i++ {
		go Count(lock)
	}
	for {
		lock.Lock()
		c := counter
		lock.Unlock()
		runtime.Gosched()
		if c >= 10 {
			break
		}
	}
}

运行结果如下:

# command-line-arguments
./main.go:14:14: undefined: z

不要通过共享内存来通信,而应该通过通信来共享内存。

package main

import "fmt"

func Add(x, y int) {
	z := x + y
	fmt.Println(z)
}

func main() {
	for i := 0; i < 10; i++ {
		go Add(i, i)
	}
}

无运行结果。

通道(Channel)

代码如下:

package main

import (
	"fmt"
)

func Count(ch chan int) {
	ch <- 1
	fmt.Println("Counting")
}

func main() {
	chs := make([]chan int, 10)
	for i := 0; i < 10; i++ {
		chs[i] = make(chan int)
		go Count(chs[i])
	}
	for _, ch := range chs {
		<-ch
	}
}

1、基本语法

一般channel的声明形式为:

var chanName chan ElementType

在channel的用法中,最常见的包括写入和读出。

将一个数据写入(发送)到channel的语法很直观:

ch <- value

从channel中读取数据的语法是:

value:=<-ch

2、select

Go语言直接在语言级别支持select关键字,用于处理异步I/O问题。

3、缓冲机制

4、超时和计时器

5、channel的传递

6、单向channel

7、关闭channel

使用go语言内置的close()函数如下:

close(ch)

并发进阶

1、多核并行化

2、协程同步

只有在当需要告诉接受者不会再提供新的值的时候,才需要关闭通道。

只有发送者需要关闭通道,接收都永远不会需要。

代码如下:

package main

import (
	"fmt"
	"time"
)

func sendData(ch chan string) {
	ch <- "纽约"
	ch <- "华盛顿"
	ch <- "伦敦"
	ch <- "北京"
	ch <- "东京"
}

func getData(ch chan string) {
	var input string
	for {
		input = <-ch
		fmt.Printf("%s ", input)
	}
}

func main() {
	ch := make(chan string)
	go sendData(ch)
	go getData(ch)
	time.Sleep(1e9)
}

运行结果如下:

纽约 华盛顿 伦敦 北京 东京 

代码如下:

package main

import (
	"fmt"
)

func sendData(ch chan string) {
	ch <- "纽约"
	ch <- "华盛顿"
	ch <- "伦敦"
	ch <- "北京"
	ch <- "东京"
	close(ch)
}

func getData(ch chan string) {
	for {
		input, open := <-ch
		if !open {
			break
		}
		fmt.Printf("%s ", input)
	}
}

func main() {
	ch := make(chan string)
	go sendData(ch)
	getData(ch)
}

运行结果如下:

纽约 华盛顿 伦敦 北京 东京 

为一个普通函数创建goroutine的写法如下:

go 函数名(参数列表)

函数名:要调用的函数名。

参数列表:调用函数需要传入的参数。

使用go关键字创建goroutine时,被调用函数的返回值会被忽略。

代码如下:

package main

import (
	"fmt"
	"time"
)

func running() {
	var times int
	//构建一个无限循环
	for {
		times++
		fmt.Println("tick", times)
		//延时1秒
		time.Sleep(time.Second)
	}
}

func main() {
	//并发执行程序
	go running()
	//接受命令行输入,不做任何事情
	var input string
	fmt.Scanln(&input)
}

使用匿名函数创建goroutine的格式

go func (参数列表) {

        函数体

} (调用参数列表)

参数列表:函数体内的参数变量列表

函数体:匿名函数的代码。

调用参数列表:启动goroutine时,需要向匿名函数传递的调用函数。

代码如下:

package main

import (
	"fmt"
	"time"
)

func main() {

	go func() {
		var times int
		for {
			times++
			fmt.Println("tick", times)
			time.Sleep(time.Second)
		}
	}()
	var input string
	fmt.Scanln(&input)
}

调整并发的运行恒通(GOMAXPROCS)

格式如下:

runtime.GOMAXPROCS(逻辑CPU数量)

这里的逻辑CPU数量可以有如下几种数值:

<1:不修改任何数值。

=1:单核心执行。

>1:多核并发执行。

一般情况下,可以使用funtime.NumCPU()查询CPU数量 ,并使用runtime.GOMAXPROCS()函数进行设置,例如:

runtime.GOMAXPROCS(runtime.NumCPU())

理解并发和并行

并发(concurrency):把任务在不同的时间点交给处理器进行处理。在同一个时间点,任务并不会同时运行。

并行(parallelism):把每一个任务分配给每一个处理器独立完成。在同一个时间点,任务一定是同时运行。

代码如下:

package main

import (
	"fmt"
)

func sum(values []int, resultChan chan int) {
	sum := 0
	for _, value := range values {
		sum += value
	}
	resultChan <- sum		//将计算结果发送到channel中
}

func main() {
	values := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	resultChan := make(chan int, 2)
	go sum(values[:len(values)/2], resultChan)
	go sum(values[len(values)/2:], resultChan)
	sum1, sum2 := <-resultChan, <-resultChan		//接收结果
	fmt.Println("Result:", sum1, sum2, sum1+sum2)
}

运行结果如下:

Result: 40 15 55

去程:

代码如下:

package main

import (
	"fmt"
	"time"
)

func sheep(i int) {
	for ; ; i += 2 {
		fmt.Println(i, "只羊")
	}
}

func main() {
	go sheep(1)
	go sheep(2)
	time.Sleep(time.Millisecond)
}

运行结果如下:

2 只羊
4 只羊
6 只羊
8 只羊
10 只羊
12 只羊
14 只羊
16 只羊
18 只羊
20 只羊
22 只羊
24 只羊
26 只羊
28 只羊
30 只羊
32 只羊
34 只羊
36 只羊
38 只羊
40 只羊
42 只羊
44 只羊
46 只羊
48 只羊
50 只羊
52 只羊
54 只羊
56 只羊
58 只羊
60 只羊
62 只羊
64 只羊
66 只羊
68 只羊
70 只羊
72 只羊
74 只羊
76 只羊
78 只羊
80 只羊
82 只羊
84 只羊
86 只羊
88 只羊
90 只羊
92 只羊
94 只羊
96 只羊
98 只羊
100 只羊
102 只羊
104 只羊
106 只羊
108 只羊
110 只羊

回程:

代码如下:

package main

import (
	"fmt"
	"time"
)

var wormhole chan time.Time

func deepspace() {
	wormhole <- time.Now()
}

func main() {
	wormhole = make(chan time.Time)
	go deepspace()
	fmt.Println(<-wormhole)
}

运行结果如下:

2022-04-06 15:47:02.3888929 +0800 CST m=+0.002617601

遍历与关闭:

代码如下:

package main

import (
	"fmt"
	"time"
)

type hole chan time.Time

func deepspace(w hole, h int) {
	defer close(w)
	for ; h > 0; h-- {
		w <- time.Now()
		time.Sleep(time.Second)
	}
}

func consumer(w hole) {
	for msg := range w {
		fmt.Println("consumer", msg)
	}
}

func main() {
	w := make(hole)
	go deepspace(w, 8)
	go consumer(w)
	for {
		msg, ok := <-w
		if !ok {
			break
		}
		fmt.Println("main", msg)
	}
	fmt.Println("Done")
}

运行结果如下:

main 2022-04-09 14:52:07.041789 +0800 CST m=+0.002800701
consumer 2022-04-09 14:52:08.0456268 +0800 CST m=+1.006638501
main 2022-04-09 14:52:09.0578227 +0800 CST m=+2.018834401
consumer 2022-04-09 14:52:10.0705782 +0800 CST m=+3.031589901
main 2022-04-09 14:52:11.0742367 +0800 CST m=+4.035248401
consumer 2022-04-09 14:52:12.0782694 +0800 CST m=+5.039281101
main 2022-04-09 14:52:13.0930031 +0800 CST m=+6.054014801
consumer 2022-04-09 14:52:14.0936872 +0800 CST m=+7.054698901
Done

MapReduce:

映射化简:每个去程对应一个Map并发执行,结果写入缓冲程道,最后再用一个Reduce函数综合这个程道得到的每一个值。

代码如下:

package main

import (
	"fmt"
	"math/rand"
)

type hole chan int

func deepspace(w hole) {
	w <- rand.Int()
}

func main() {
	n := 8
	w := make(hole, n)
	//Map
	for i := 0; i < n; i++ {
		go deepspace(w)
	}
	//Reduce
	t := 0
	for i := 0; i < n; i++ {
		t += <-w
	}
	fmt.Println("Total:", t)
}

运行结果 如下:

Total: -174686420686987236

两个goroutine进行并行的累加计算:代码如下:

package main

import (
	"fmt"
)

func sum(values []int, resultChan chan int) {
	sum := 0
	for _, value := range values {
		sum += value
	}
	resultChan <- sum
}

func main() {
	values := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	resultChan := make(chan int, 2)
	go sum(values[:len(values)/2], resultChan)
	go sum(values[len(values)/2:], resultChan)
	sum1, sum2 := <-resultChan, <-resultChan
	fmt.Println("Result:", sum1, sum2, sum1+sum2)
}

运行结果如下:

Result: 40 15 55

select语句:

代码如下:

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type hole chan int

func deepspace(w hole, h int) {
	defer close(w)
	d := time.Duration(rand.Intn(h)) * time.Second
	for ; h > 0; h-- {
		w <- rand.Int()
		time.Sleep(d)
	}
}

func main() {
	n := 8
	w := make(hole)
	t := 0
	maxTime := time.Second
	go deepspace(w, n)
Out:
	for i := 0; i < n; i++ {
		select {
		case n := <-w:
			t += n
		case <-time.After(maxTime):
			fmt.Println("Time out")
			break Out
		}
	}
	fmt.Println("Total:", t)
}

运行结果如下:

Time out
Total: 8674665223082153551

程道值:

代码如下:

package main

import (
	"fmt"
)

type Read struct {
	key   string
	reply chan<- string
}

type Write struct {
	key string
	val string
}

var hole = make(chan interface{})

func deepspace() {
	m := map[string]string{}
	for {
		switch r := (<-hole).(type) {
		case Read:
			r.reply <- m[r.key] + " from Mars."
		case Write:
			m[r.key] = r.val
		}
	}
}

func main() {
	go deepspace()
	hole <- Write{"Name", "Martin"}
	home := make(chan string)
	hole <- Read{"Name", home}
	fmt.Println(<-home)
}

运行结果如下:

Martin from Mars.

Go语言学习笔记—golang并发编程之channel 视频来源于B站Go语言基础进阶视频av56860636 文章为自己整理的学习笔记,侵权即删,谢谢支持! 阅读详情

相关推荐

ERA5数据驱动WRFV4.4实战:单层嵌套配置与关键报错排查指南

本文详细介绍了使用ERA5再分析数据驱动WRFV4.4模式进行单层嵌套模拟的完整实战流程。内容涵盖从数据精准下载、WPS前处理配置、WRF核心参数设置到高频报错的深度排查与解决方案,旨在帮助初学者在有限服务器资源下,高效完成WRF模拟并规避常见陷阱。

q5r6s7的博客 770

Go 并发编程

关于 Go 语言之高性能并发编程的基础知识!

qq_46457076的博客 1580

iSLIP算法实战:如何用Python模拟交换机优先级匹配(附完整代码)

本文详细介绍了如何使用Python实现iSLIP算法,模拟交换机优先级匹配过程。通过核心的指针滑动逻辑和迭代循环策略,构建了一个完整的iSLIP算法模拟器,并加入可视化模块以直观展示匹配过程。文章还提供了完整的代码框架和性能优化建议,适合网络工程师和Python开发者直接集成到测试环境中。

weixin_29313239的博客 249

Go语言并发编程

go语言并发编程、加锁、并发。

weixin_46042817的博客 1379

Day2 十分钟带你解决逆向中对称加密算法 (RC4)

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种串流加密算法,密钥长度可变。他加密解密使用相同的密钥,因此也被称为“流加密算法”。RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。由于异或运算的对合性,RC4加密解密使用同一套算法。

m0_73779708的博客 1289

在Ubuntu 20.04上,用EtherCAT Igh 1.6.2驱动高创BD3E伺服电机(附完整C代码)

本文详细介绍了在Ubuntu 20.04实时内核环境下,使用EtherCAT Igh 1.6.2主站驱动高创BD3E伺服电机的完整实现方案。从实时系统配置、伺服电机PDO映射到精确控制线程设计,提供了完整的C代码样例和实际项目中的调试技巧,帮助开发者实现工业自动化中的高精度运动控制。

weixin_30772105的博客 110

GO并发编程

无缓冲channel:本质是一种同步通道,他要求读写操作紧密进行。所以,在单channel下,如果在无缓冲channel中进行读写,此时就会在第一次操作处阻塞,发生死锁。

2303_79380171的博客 1638

物理机centos7系统重启后直接进入dracut

Warning: /dev/centos/root does not exist Warning: /dev/mapper/centos-root does not exist 在shell命令行执行以下: dracut:/# lvm vgscan dracut:/# lvm vgchange -ay dracut:/# exit 之后可以正常进入系统(测试正常)。 但是重启之后依然会进入dracut模式,永久解决如下: 查看kernel文件 [root@ecs ~]# ls -ltrh /boot

魏志标的博客 1万+

Go语言并发详解

文章目录一、Go语言并发简述(并发的优势)进程/线程并发/并行协程/线程Goroutine 介绍channel二、Go语言goroutine(轻量级线程)使用普通函数创建 goroutine1) 格式2) 例子使用匿名函数创建goroutine1) 使用匿名函数创建goroutine的格式2) 使用匿名函数创建goroutine的例子提示三、Go语言并发通信四、Go语言竞争状态简述Goroutine 7 (finished) created at: main.main() D:/code/src/m

qq_41854911的博客 1万+

STM32F103ZET6驱动57闭环步进电机(连线+代码)

一、设备: 1. STM32F103开发板 (普中F103的板子) 2. 57闭环电机带驱动 3. 24V/3A的直流电源,用于给电机驱动供电 简单说明:使用Keil5编程,主要使用了PWM波,外部中断和时间中断,按键控制电机使能和脱机并且控制PWM的周期,调节周期即调节电机的转速。 二、STM32开发板与电机驱动的连线: 1.PUL-、ENA-、DIR-与STM32的连接方法: 可以参考CSND的这个链接中的说明,使用共阴极接法:STM32F407-用TB6600驱动器驱动57步进电机(代码

baidu_39071234的博客 7430

【YOLO多模态检测顶刊】TGRS 2025范文解读,RGFNet 可见光-红外图像融合目标检测,2026年基于YOLO多模态融合属于发文热点,小论文和大论文通用,通读顶刊了解做实验和论文写作的全流程

🔥本文提出了一种反射率引导的渐进特征对齐网络(RGFNet)用于全天候无人机目标检测。该方法利用Retinex理论从可见光图像中提取光照不变的反射率特征,设计了反射率引导协同对齐模块(RCAM)实现跨模态双向特征对齐,并通过光照感知选择性融合模块(LSFM)在共享状态空间中进行高效特征交互。在DroneVehicle和DVTOD数据集上的实验表明,RGFNet分别达到81.4%和88.5%的mAP,显著优于现有方法。该方法有效解决了低光照条件下可见光-红外图像特征错位问题,为全天候无人机检测提供了新思路。

Ai缝合怪、助力小伙伴高效发论文 1078

【golang学习之旅】Go 语言并发编程(goroutine、channel 的使用)

✅ 适合人群:Golang 开发者 | 并发编程初学者 | 后端开发工程师✅ 文章亮点:深入解析 Goroutine & Channel + 代码示例 + 实战场景✅ 目标:掌握 Go 并发编程核心,让你的代码更高效、更强大!Goroutine是Go语言的轻量级线程,由Go运行时管理,而非操作系统。相比传统线程,Goroutine占用内存小:默认仅2KB栈空间,可动态扩展调度高效:Go运行时管理Goroutine的调度,无需手动创建线程启动成本低:创建Goroutine比创建线程的开销小很多。

程序员林北北的博客 1252

PMO与供应链管理的整合:端到端项目交付的优化策略

在当今全球化和市场竞争日益激烈的环境中,组织面临着前所未有的项目复杂性和交付压力。传统上相互独立的项目管理办公室(PMO)与供应链管理(SCM)正逐渐意识到:只有通过无缝整合,才能实现真正高效的端到端项目交付。本文深入探讨了PMO与供应链管理整合的战略价值、核心框架和实施路径,通过生动的比喻、实际案例和实用工具,展示了如何打破部门壁垒,构建协同高效的项目生态系统。无论您是PMO负责人、供应链专业人士还是高级管理层,都将从本文获得重塑项目交付模式、优化资源利用、降低风险并提升组织竞争力的宝贵见解和行动指南。

项目管理的博客 947

Go 语言(Golang)并发编程通俗易懂案例

Go 语言(Golang)天生支持并发编程,它的并发模型基于轻量级的 goroutine 和通信顺序进程(CSP)的思想。Goroutine 是 Go 语言中的并发执行单元,通过通道(channel)来实现不同 goroutine 之间的通信。

weixin_43425950的博客 880

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

14 go语言(golang) - 并发编程goroutine和channel

并发编程是指在计算机程序中同时执行多个计算任务的技术。这种编程方式旨在利用多核处理器的计算能力,提高程序的执行效率和响应速度。而Go 语言的并发编程主要依赖于两个核心概念:Goroutine 和 Channel。

瑞瑞的博客 1076

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

golang笔记10--go语言并发编程模块 goroutine

golang笔记10--go语言的并发编程模块 goroutine1 介绍2 Goroutine2.1 goroutine2.2 go语言的调度器3 注意事项4 说明 1 介绍 本文继上文 golang笔记09–go语言测试与性能调优, 进一步了解 go语言的并发编程模块 --goroutine,以及相应注意事项。 具体包括 : goroutine 和 go语言的调度器 等内容。 2 Goroutine 2.1 goroutine 主流的并发模型包括:多进程、多线程、基于回调的非阻塞|异步IO、协程 等方式

脚步不能达到的地方,眼光可以达到;眼光不能达到的地方,精神可以飞到 474

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【go语言】并发编程

是一个用于描述程序中操作之间因果顺序的规则。在并发编程中,happen-before 机制定义了如何确保一个操作在另一个操作之前发生,并且保证一个操作的结果能够对其他操作可见。具体而言,程序顺序规则(Program Order Rule):在同一个 goroutine 内,代码的执行顺序是保证的,即一个操作发生在前一个操作之后。同步规则(Synchronization Rule):一个 goroutine 对 channel 的发送操作(ch <- x。

加油,考上985的研究生 1471

golang笔记11--go语言并发编程模块 channel

golang笔记11--go语言并发编程模块 channel1 介绍2 Channel2.1 channel2.2 使用Channel等待任务结束2.3 使用Channel进行树的遍历2.4 用select进行调度2.5 传统同步机制3 注意事项4 说明 1 介绍 本文继上文 golang笔记10–go语言并发编程模块 goroutine, 进一步了解 go语言的并发编程模块 --channel,以及相应注意事项。 具体包括 : channel、使用Channel等待任务结束、使用Channel进行树的遍历

脚步不能达到的地方,眼光可以达到;眼光不能达到的地方,精神可以飞到 542

16 go语言(golang) - 并发编程select和workerpool

首先,定义一个WorkerPool最大工作者数(maxWorkers:控制同时运行的 goroutine 的最大数量。任务队列(taskQueue:用于存储待处理任务,通常使用channel来实现。停止信号(stopSignal:一个通道,用于发送停止信号给所有工作者,让它们停止执行。同步机制:如互斥锁(sync.Mutex)或 WaitGroup(),用于同步和等待所有工作者完成。// 池stopSignal chan int // 停止信号,接受到数据时时停止// 保证停止后不能再提交任务。

瑞瑞的博客 1287
上一篇: 9. Palindrome Number回文数(Easy,LeetCode)
下一篇: Go语言的网络编程
DXB2021
博客等级 码龄5年 307粉丝 289原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值