package main;

import (
"fmt"
"sync"
"runtime"
"time"
) //加锁,注意锁要以指针的形式传进来,不然只是拷贝
func total1(num *int, mu *sync.Mutex, ch chan bool) {
mu.Lock();
for i := 0; i < 1000; i++ {
*num += i;
}
ch <- true;
mu.Unlock();
} //不加锁
func total2(num *int, ch chan bool) {
for i := 0; i < 1000; i++ {
*num += i;
}
ch <- true;
} //Lock、Unlock与RLock、RUnlock不能嵌套使用
func total3(num *int, rwmu *sync.RWMutex, ch chan bool) {
for i := 0; i < 1000; i++ {
rwmu.Lock();
*num += i;
rwmu.Unlock(); if(i == 500) {
//读锁定
rwmu.RLock();
fmt.Print(*num, " ");
rwmu.RUnlock();
}
}
ch <- true;
} func printNum(num int, cond *sync.Cond) {
cond.L.Lock();
if num < 5 {
//num小于5时,进入等待状态
cond.Wait();
}
//大于5的正常输出
fmt.Println(num);
cond.L.Unlock();
} func main() {
//Once.Do()保证多次调用只执行一次
once := sync.Once{};
ch := make(chan bool, 3);
for i := 0; i < 3; i++ {
go func(n int) {
once.Do(func() {
//只会执行一次,因为闭包引用了变量n,最后的值为2
fmt.Println(n)
});
//给chan发送true,表示执行完成
ch <- true;
}(i);
}
for i := 0; i < 3; i++ {
//读取三次chan,如果上面三次没执行完会一直阻塞
<-ch;
} //互斥锁,保证某一时刻只能有一个访问对象
mutex := sync.Mutex{};
ch2 := make(chan bool, 20);
//使用多核,不然下面的结果会一样
runtime.GOMAXPROCS(runtime.NumCPU());
num1 := 0;
num2 := 0;
for i := 0; i < 10; i++ {
go total1(&num1, &mutex, ch2);
}
for i := 0; i < 10; i++ {
go total2(&num2, ch2);
}
for i := 0; i < 20; i++ {
<-ch2;
}
//会发现num1与num2计算出的结果不一样
//而num1的结果才是正确的,因为total2没有加锁,导致多个goroutine操作num时发生数据混乱
fmt.Println(num1, num2); //读写锁,多了读锁定,和读解锁,让多个goroutine同时读取对象
rwmutex := sync.RWMutex{};
ch3 := make(chan bool, 10);
num3 := 0;
for i := 0; i < 10; i++ {
go total3(&num3, &rwmutex, ch3);
}
for i := 0; i < 10; i++ {
<-ch3;
}
fmt.Println(num3); //组等待,等待一组goroutine的结束
wg := sync.WaitGroup{};
//增加计数器
wg.Add(10);
for i:= 0; i< 10; i++ {
go func(n int) {
fmt.Print(n, " ");
//这里表示该goroutine执行完成
wg.Done();
}(i);
}
//等待所有线程执行完成
wg.Wait(); fmt.Println(""); //条件等待
mutex2 := sync.Mutex{};
//使用锁创建一个条件等待
cond := sync.NewCond(&mutex2); for i := 0; i < 10; i++ {
go printNum(i, cond);
} time.Sleep(time.Second * 1);
//等待一秒后,我们先唤醒一个等待,输出一个数字
cond.L.Lock()
cond.Signal();
cond.L.Unlock();
time.Sleep(time.Second * 1);
//再次待待一秒后,唤醒所有,输出余下四个数字
cond.L.Lock()
cond.Broadcast();
cond.L.Unlock();
time.Sleep(time.Second * 1);
}

  

go语言sync包的学习(Mutex、WaitGroup、Cond)的更多相关文章

  1. go语言time包的学习(Time,Location,Duration,Timer,Ticker)

    package main;   import (     "time"     "fmt" )   func main() {     //time.Time代 ...

  2. go语言log包的学习(log,Logger)

    package main; import ( "log" "os" "time" "fmt" ) func main() ...

  3. go语言path包和filepath包的学习与使用

    path包的使用 package main; import ( "fmt" "path" ) //go语言path包的学习 func main() { //返回 ...

  4. R语言 ggplot2包

    R语言  ggplot2包的学习   分析数据要做的第一件事情,就是观察它.对于每个变量,哪些值是最常见的?值域是大是小?是否有异常观测? ggplot2图形之基本语法: ggplot2的核心理念是将 ...

  5. Go中sync包学习

    前面刚讲到goroutine和channel,通过goroutine启动一个协程,通过channel的方式在多个goroutine中传递消息来保证并发安全.今天我们来学习sync包,这个包是Go提供的 ...

  6. golang 中 sync包的 WaitGroup

    golang 中的 sync 包有一个很有用的功能,就是 WaitGroup 先说说 WaitGroup 的用途:它能够一直等到所有的 goroutine 执行完成,并且阻塞主线程的执行,直到所有的 ...

  7. 从实例学习 Go 语言、"并发内容" 学习笔记及心得体会、Go指南

    第一轮学习 golang "并发内容" 学习笔记,Go指南练习题目解析.使用学习资料 <Go-zh/tour tour>.记录我认为会比较容易忘记的知识点,进行补充,整 ...

  8. Sync包

    sync同步包 Mutex互斥锁: 能够保证在同一时间段内仅有一个goroutine持有锁,有且仅有一个goroutine访问共享资源,其他申请锁的goroutine将会被阻塞直到锁被释放.然后重新争 ...

  9. go语言中sync包和channel机制

    文章转载至:https://www.bytelang.com/article/content/A4jMIFmobcA= golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"Go&quo ...

随机推荐

  1. 如何使用JBDC修改数据

    1.JDBC取得数据库Connection连接对象conn, Connection conn=null;   //数据库连接对象 String strSql=null;    //sql语句对象 // ...

  2. Ldap-crack-test?

    ldap #!/bin/env python import sys import ldap ldapconn = ldap.initialize('ldap://domain.adserve.com' ...

  3. 设置DNS 代理

    最近烦心事好多啊,坑爹的中介... 公司之前因为断电,导致DNS基础服务故障,很多系统好半天在能使用,所以这次吸取教训,设置备份的DNS server以及使得DNS能够动态迁移,在这种时候就显得格外的 ...

  4. ArcGIS(ESRI)的发展历史和版本历史(简介)

    作者:fenghuayoushi 来源:CSDN 原文:https://blog.csdn.net/fenghuayoushi/article/details/6677360   ESRI公司介绍   ...

  5. 学JS的心路历程-JS支持面向对象?(一)

    昨天在看Prototype看到JS支持面向对象,被前辈问到说那什么是面向对象?JS是面向对象语言吗? 便开始了一连串艰辛爬文过程,今天就来看一下两者有什么差异吧(rgwyjc)! 首先面向对象有三大特 ...

  6. HTTP是用来做什么的

    (一)HTTP协议介绍 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目 ...

  7. python 自然语言处理库https://www.nltk.org/nltk_data/

    https://www.nltk.org/nltk_data/ https://github.com/hankcs/HanLP

  8. support:design:26.1.0

    https://blog.csdn.net/qzltqdf3179103/article/details/79583491 compileSdkVersion 26buildToolsVersion ...

  9. Controlled Components

    [Controlled Components] In HTML, form elements such as <input>, <textarea>, and <sele ...

  10. numpy--深度学习中的线代基础

    参考自 微信公众号--深度学习世界(http://mp.weixin.qq.com/s?__biz=MzI4MDMwMDM3NA==&mid=2247484616&idx=1& ...