10.Go-goroutine,waitgroup,互斥锁和channel
10.1.goroutine
goroutine的使用
//Learn_Go/main.go
package main import (
"fmt"
"time"
) func demo(count int) {
for i :=1; i < 10; i++{
fmt.Println(count,":",i)
}
} func main() {
for i :=1; i < 10; i++{
go demo(i)
}
//添加休眠时间等待goroutine执行结束
time.Sleep(3e9)
}
10.2.waitgroup
WaitGroup直译为等待组,其实就是计数器,只要计数器中有内容将一直阻塞
WaitGroup有三种方法
- Add(delta int)表示向内部计数器添加增量(delta),其中参数delta可以使负数
- Done() 表示减少waitgroup计数器的值,应当在程序最后执行,相当于Add(-1)
- Wait() 表示阻塞知道waitgroup计数器为0
//Learn_Go/main.go
package main import (
"fmt"
"sync"
) func main() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++{
go func(j int) {
fmt.Println("第",j,"次执行")
wg.Done()
}(i)
}
wg.Wait()
fmt.Println("程序结束")
}
10.3.互斥锁和读写锁
(1)互斥锁
可以使用sync.Mutex对内容加锁,互斥锁的使用场景
- 多个gouroutine访问同一个函数代码段
- 操作一个全局变量
- 为了保证共享变量安全性,值安全性
(2)读写锁
Go语言中的map不是线程安全的,多个gouroutine同时操作会出现错误
RWMutex可以添加多个读锁或者一个写锁,读写锁不能同时存在
map在并发下读写就需要结合读写锁完成
互斥锁表示锁的代码同一时间只能有一个goroutine运行,而读写锁表示在锁范围内数据的读写操作
//Learn_Go/main.go
package main import (
"fmt"
"sync"
) func main() {
var rwm sync.RWMutex
var wg sync.WaitGroup
wg.Add(10)
m := make(map[int]int)
for i := 0; i < 10; i++{
go func(j int) {
rwm.Lock()
m[j] = j
fmt.Println(m)
rwm.Unlock()
wg.Done()
}(i)
}
wg.Wait()
fmt.Println("程序结束")
}
10.4.channel
channel是进程内通信方式,每个channel只能传递一个类型的值,这个类型需要在声明channel时指定
channel在Go中主要的两个作用:同步和通信
(1)声明channel的语法
- var 名称 chan 类型
- var 名称 chan <- 类型 只写
- var 名称 <- chan 类型 只读
- 名称 := make(chan int) 无缓存chanel
- 名称 := make(chan int) 无缓存channel
- 名称 := make(chan int,100) 有缓存channel
(2)操作channel的语法
- ch <- 值 向ch中添加一个值
- <- ch 从ch中取出一个值
- a := <-ch 从ch中取出一个值并赋值给a
- a,b := <-ch 从ch中取出一个值赋值给a,如果ch已经关闭或ch中没有值,b为false,
(3)无论是向channel存数据还是取数据都会阻塞
//Learn_Go/main.go
package main import "fmt" func main() {
ch := make(chan int)
go func() {
fmt.Println("执行")
ch <- 111
}()
a := <- ch
fmt.Println(a)
fmt.Println("程序结束")
}
(4)使用channel实现gouroutine之间通信
//Learn_Go/main.go
package main import "fmt" func main() {
ch1 := make(chan string)
ch2 := make(chan int) go func() {
ch1 <- "derek"
ch2 <- 111
}() go func() {
content := <- ch1
fmt.Println("取出数据:",content) //取出数据: derek
ch2 <- 222
}() a := <- ch2
b := <- ch2
fmt.Println(a,b) //111 222
fmt.Println("程序结束")
}
(5)可以使用for range获取channel中内容
//Learn_Go/main.go
package main import "fmt" func main() {
ch1 := make(chan int)
ch2 := make(chan int) go func() {
for i := 0; i<10;i++{
ch1 <- i
}
ch2 <- 222
}() go func() {
for n := range ch1{
fmt.Println(n)
}
}()
<- ch2
fmt.Println("程序结束")
}
10.5.select
select执行过程
- 每个case必须是一个IO操作
- 哪个case可以执行就执行哪个
- 所有case都不能执行时,执行default
- 所有case都不能执行且没有default,将会阻塞
//Learn_Go/main.go
package main import "fmt" func main() {
ch1 := make(chan int,2) //有缓存的channel
ch2 := make(chan int,3)
ch1 <- 111
ch2 <- 222
select {
case a := <-ch1:
fmt.Println(a)
case b := <-ch2:
fmt.Println(b)
default:
fmt.Println("错误")
}
}
select多和for循环结合使用
//Learn_Go/main.go
package main import "fmt" func main() {
ch := make(chan int)
for i := 0; i < 10;i++{
go func(j int) {
ch <- j
}(i)
}
//用for循环一直接受
for {
select {
case a := <- ch:
fmt.Println(a)
default:
}
}
}
10.Go-goroutine,waitgroup,互斥锁和channel的更多相关文章
- 10.Go-goroutine,waitgroup,互斥锁,channel和select
10.1.goroutine goroutine的使用 //Learn_Go/main.go package main import ( "fmt" "time" ...
- liteos互斥锁(七)
1. 概述 1.1 基本概念 互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理. 任意时刻互斥锁的状态只有两种,开锁或闭锁.当有任务持有时,互斥锁处于闭锁状态,这个任务 ...
- 多图详解Go的互斥锁Mutex
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码时14.4 Mutex介绍 Mutex 结构体包含两个字段: 字段s ...
- 鸿蒙内核源码分析(互斥锁篇) | 比自旋锁丰满的互斥锁 | 百篇博客分析OpenHarmony源码 | v27.02
百篇博客系列篇.本篇为: v27.xx 鸿蒙内核源码分析(互斥锁篇) | 比自旋锁丰满的互斥锁 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁当立贞 ...
- goroutiine同步/channel、互斥锁、读写锁、死锁/条件变量
1. Goroutine同步[数据同步] 为什么需要goroutine同步 gorotine同步概念.以及同步的几种方式 1.1 为什么需要goroutine同步 package main impor ...
- Go基础系列:互斥锁Mutex和读写锁RWMutex用法详述
sync.Mutex Go中使用sync.Mutex类型实现mutex(排他锁.互斥锁).在源代码的sync/mutex.go文件中,有如下定义: // A Mutex is a mutual exc ...
- Go语言基础之13--线程安全及互斥锁和读写锁
一.线程安全介绍 1.1 现实例子 A. 多个goroutine同时操作一个资源,这个资源又叫临界区 B. 现实生活中的十字路口,通过红路灯实现线程安全 C. 火车上的厕所(进去之后先加锁,在上厕所, ...
- Go同步等待组/互斥锁/读写锁
1. 临界资源 package main import ( "fmt" "time" ) func main() { /* 临界资源: */ a := 1 go ...
- Go语言中的互斥锁和读写锁(Mutex和RWMutex)
目录 一.Mutex(互斥锁) 不加锁示例 加锁示例 二.RWMutex(读写锁) 并发读示例 并发读写示例 三.死锁场景 1.Lock/Unlock不是成对出现 2.锁被拷贝使用 3.循环等待 虽然 ...
随机推荐
- PAT L3-002: 堆栈(线段树)
https://www.patest.cn/contests/gplt/L3-002 题意:中文题意. 思路:因为所有数<=1e5,权值线段树维护每个数出现多少次,然后每次出栈入栈都更新权值就好 ...
- HDU 3338:Kakuro Extension(脑洞大开的网络流)
http://acm.hdu.edu.cn/showproblem.php?pid=3338 题意:在一个n*m的地图里面,有黑方块和白方块,黑方块可能是“XXXXXXX”或者“YYY/YYY”,这里 ...
- Ceph Plugin - Dashboard - By Anoyi
▶ 部署 Dashboard 1.安装 ceph-mgr-dashboard yum install -y ceph-mgr-dashboard 2.禁用 SSL ceph config set mg ...
- Node.js热部署代码,实现修改代码后自动重启服务方便实时调试
写PHP等脚本语言的时候,已经习惯了修改完代码直接打开浏览器去查看最新的效果.而Node.js 只有在第一次引用时才会去解析脚本文件,以后都会直接访问内存,避免重复载入,这种设计虽然有利于提高性能,却 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
- Spring Cloud Alibaba | Nacos集群部署
目录 Spring Cloud Alibaba | Nacos集群部署 1. Nacos支持三种部署模式 2. 集群模式下部署Nacos 2.1 架构图 2.2 下载源码或者安装包 2.3 配置集群配 ...
- 「Sqlserver」数据分析师有理由爱Sqlserver之二-像使用Excel一般地使用Sqlserver
大家一谈数据库,就觉得非常高深莫测,深不见底,非凡人敢去触摸.但Excel的话,没人敢说自己不会使用吧(相反一大堆人的简历上写着精通OFFICE所有软件套件).换作其他非微软厂商的数据库,的确很容易产 ...
- fjnuoj 1003 学长的QQ号
题目: //QQ是一个9位数,由1,2,3,4,5,9组成,且第1.6位数字相同,第2.4位数字相同,第5.7位数字相同. //我的QQ就在符合上诉条件中的所有9位数从小到大排第 ...
- Spring Boot 面试的十个问题
用下面这些常见的面试问题为下一次 Spring Boot 面试做准备. 在本文中,我们将讨论 Spring boot 中最常见的10个面试问题.现在,在就业市场上,这些问题有点棘手,而且趋势日益严重. ...
- VS Code 安装 LeetCode 插件
练习算法绕不开的一个网站就是力扣,很多小伙伴为了拿到大厂 offer,刷题都刷到吐了. 然而如果直接在 LeetCode 上写代码,那是很痛苦的一件事,那就相当于用 txt 写代码一样,没有 IDE ...