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.循环等待 虽然 ...
随机推荐
- POJ 2679:Adventurous Driving(SPFA+DFS)
http://poj.org/problem?id=2679 Adventurous Driving Time Limit: 1000MS Memory Limit: 65536K Total S ...
- SpringMVC框架的简单理解
首先,让我们来看下下图 SpringMVC解决了View和Controller的交互问题 其中有几个重要组成部分: (1) DispatcherServlet: 前端控制器 用于接收所有请求,并负责分 ...
- 《深入浅出MFC》下载
百度云及其他网盘下载地址:点我 编辑推荐 <深入浅出MFC>内含光盘一片,书中所有原始码与可执行文件尽在其中. 作者简介 侯俊杰,先生不知何许人也,闲静少言,不慕荣利.好读书,求甚解:每有 ...
- Java NIO学习系列四:NIO和IO对比
前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...
- 深度总结eMMC发展史 ICMAX值得更好地期待
随着大数据.云计算.物联网等产业的发展,信息存储安全一旦受到威胁,将危害到政军.石油.化工.核能.金融等所有行业的安全.存储芯片又被称为电子产品的“粮食”,占产品成本的二成左右,尽管中国是全球最大的手 ...
- [Haoi2016]放棋子 题解
4563: [Haoi2016]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 285[Submit][Status] ...
- Golang 高效实践之并发实践
前言 在我前面一篇文章Golang受欢迎的原因中已经提到,Golang是在语言层面(runtime)就支持了并发模型.那么作为编程人员,我们在实践Golang的并发编程时,又有什么需要注意的点呢?下面 ...
- py+appium微信公众号自动化(已搞定多个坑)
最近需要做微信公众号的自动化测试,遇到了不少坑. 微信公众号自动化与app自动化还是有区别的,因为多了不少坑.打开微信x5内核调试的就不说了,百度有. 1.首先,微信公众号有webview,uiaut ...
- C#2.0增功能04 可以为 null 的类型
连载目录 [已更新最新开发文章,点击查看详细] 可以为 null 的类型是 System.Nullable<T> 结构的实例. 可以为 null 的类型可表示一个基础类型的所有值 T ...
- fjnuoj 1003 学长的QQ号
题目: //QQ是一个9位数,由1,2,3,4,5,9组成,且第1.6位数字相同,第2.4位数字相同,第5.7位数字相同. //我的QQ就在符合上诉条件中的所有9位数从小到大排第 ...