Golang sync
Go1.9.2 sync库里包含下面几类:Mutex/RWMutex/Cond/WaitGroup/Once/Map/Pool
1.Mutex:互斥锁,等同于linux下的pthread_mutex_t
//多个线程同时运行,获得Mutex锁者线程优先执行,其余线程阻塞等待
func testMutex() {
mutex := sync.Mutex{};
for i := ; i < ; i++ {
go func(idx int) {
mutex.Lock();
defer mutex.Unlock();
fmt.Println("idx :=", idx);
time.Sleep(time.Second);
}(i)
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}
2.RWMutex:读写锁,等同于linux下的pthread_rwlock_t
//写请求在读锁和写锁时都必须阻塞等待,读请求只在写锁时阻塞等待
func testRWMutex() {
rwMutex := sync.RWMutex{};
for i := ; i < ; i++ {
go func(idx int) {
rwMutex.RLock();
defer rwMutex.RUnlock();
fmt.Println("Read Mutex :",idx);
}(i); go func(idx int) {
rwMutex.Lock();
defer rwMutex.Unlock();
fmt.Println("Write Mutex :",idx);
time.Sleep(time.Second);
}(i);
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}
3.Cond:条件变量,等同于linux下的pthread_cond_t
func testCond() {
cond := sync.NewCond(&sync.Mutex{}); cond.L.Lock(); //①上锁
defer cond.L.Unlock(); go func() {
fmt.Println("go wait lock.");
cond.L.Lock(); //②等Wait解锁 defer cond.L.Unlock(); //⑤解锁后触发Wait
defer fmt.Println("go unlock."); fmt.Println("go locked.");
cond.Signal(); //④触发Wait等待解锁
}() time.Sleep(time.Second); fmt.Println("start wait.");
for {
cond.Wait(); //③可以理解为立刻解锁并触发一个阻塞线程(如果没有阻塞线程则不触发)后立刻再上锁等待Signal信号
fmt.Println("wait finish.");
break;
} time.Sleep(time.Second);
fmt.Println("Func finish.");
}
4.WaitGroup:组等待
//Add 增加等待计数;Done减少等待计数;当计数为0时触发Wait;
func testWaitGroup() {
waitGroup := sync.WaitGroup{};
for i := ; i < ; i++ {
waitGroup.Add(); go func(idx int) {
time.Sleep(time.Second);
fmt.Println("go : ", idx);
waitGroup.Done();
}(i)
} for{
fmt.Println("start wait.");
waitGroup.Wait();
fmt.Println("wait finish.");
break;
} time.Sleep(time.Second);
fmt.Println("Func finish.");
}
5.Once:只执行一次
//只执行一次以后不再触发
func testOnce() {
once := sync.Once{};
for i := ; i < ; i++ {
go func(idx int) {
once.Do(func() {
fmt.Println("Do once : ", idx); //这里只执行一次
}) fmt.Println("go : ", idx);
}(i)
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}
6.Map:线程安全map
func testMap() {
syncMap := sync.Map{};
for i := ; i < ; i++ {
go func(idx int) {
//如果没有则保存起来
_, ok := syncMap.LoadOrStore(idx, " StrVal = "+strconv.FormatInt(int64(idx), ));
if !ok {
fmt.Println("Store idx = ",idx);
}
}(i) go func(idx int) {
val, ok := syncMap.Load(idx);
if ok {
fmt.Println("Load success idx = ", idx, val);
} else {
fmt.Println("Load fail idx = ", idx)
}
}(i) } time.Sleep( * time.Second);
fmt.Println("Func finish.");
}
7.Pool:线程安全对象池
func testPool() {
p := &sync.Pool{
New: func() interface{} {
return -;
},
} for i := ; i < ; i++ {
go func(idx int) {
p.Put(idx);
}(i)
} //取出来的对象是无序的
for i := ; i < ; i++ {
go func() {
val := p.Get();
fmt.Println("Get val = ", val);
}()
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}
使用Pool一定要注意一下问题:
1.用途仅仅是增加对象重用的几率,减少gc的负担,而开销方面也不是很便宜的。
2.GC会将Pool清理掉。
3.Get不能保证将Put进去的全部取出来!如下例子:
func testPoolPutGet(){
myPool := &sync.Pool{
New: func() interface{} {
return ;
},
} myPool.Put() //放入1
myPool.Put() //放入2 time.Sleep(time.Second) p1 := myPool.Get().(int)
fmt.Println(p1) // 获得2 p2 := myPool.Get().(int)
fmt.Println(p2) // 获得0,而不是1!
}
4.关于Pool的实现原理,可以参考《go语言的官方包sync.Pool的实现原理和适用场景》
以上。
Golang sync的更多相关文章
- Golang Sync.WaitGroup 使用及原理
Golang Sync.WaitGroup 使用及原理 使用 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.A ...
- golang sync/atomic
刚刚学习golang原子操作处理的时候发现github上面一个比较不错的golang学习项目 附上链接:https://github.com/polaris1119/The-Golang-Standa ...
- Golang:sync.Map
由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...
- golang sync包
sync 在golang 文档上,golang不希望通过共享内存来进行进程间的协同操作,而是通过channel的方式来进行,当然,golang也提供了共享内存,锁等机制进行协同操作的包: 互斥锁: M ...
- golang sync.noCopy 类型 —— 初探 copylocks 与 empty struct
问题引入 学习golang(v1.16)的 WaitGroup 代码时,看到了一处奇怪的用法,见下方类型定义: type WaitGroup struct { noCopy noCopy ... } ...
- golang sync.Cond条件变量的使用
cond.Wait()的操作实际上是对与cond绑定的锁先进行解锁,在等待通知:接收到通知后,会尝试加锁,加锁成功则唤醒否则继续等待通知: cond.Waite()前必须对关连锁加锁,否则panic ...
- golang sync.Pool包的使用和一些注意地方
package main; import ( "sync" "fmt" "net" "runtime" ) //sync ...
- golang sync.Cond 类
众所周知,go语言在多线程方面的支持是十分完备的.在go语言sync包中提供了一个Cond类,这个类用于goroutine之间进行协作. 这个类并不复杂,只有三个函数,Broadcast() , Si ...
- golang sync.RWMutex
sync.RWMutex package main import ( "fmt" "runtime" "sync" ) func click ...
随机推荐
- 02: pycharm远程linux开发和调试代码
1.1 配置远程linux主机信息 参考博客:https://www.cnblogs.com/lei0213/p/7898301.html 1) 选择Tools--Deployment--Config ...
- mvc 前端校验
首先解决 Ajax.BeginFor异步提交表单,给表单添加样式的问题.不能直接用class属性,网上找了很多都是用ClassName,经过测试不管用,看源代码发现生成的是ClassName而非cla ...
- Codeforces Round 500 (Div 2) Solution
从这里开始 题目地址 瞎扯 Problem A Piles With Stones Problem B And Problem C Photo of The Sky Problem D Chemica ...
- Linux 使用statvfs读取文件系统信息
本文转载自:https://blog.csdn.net/papiping/article/details/6980573 在测试过程中,f_bfree的值比f_frsize的值大于10%的尺寸大小,意 ...
- repo总结【转】
本文转载自:https://blog.csdn.net/weixin_38599972/article/details/78982408 1. repo start ##创建并切换分支repo st ...
- Materialize和Material Design Lite的区别
Material Design Lite是google官方库,Materialize是第三方 Material Design Lite不依赖jquery,Materialize依赖jquery Mat ...
- 【做题】NOWCODER142A Ternary String——数列&欧拉定理
题意:你有一个长度为\(n\),且仅由012构成的字符串.每经过一秒,这个字符串所有1后面会插入一个0,所有2后面会插入一个1,然后会删除第一个元素.求这个字符串需要多少秒变为空串,对\(10^9+7 ...
- UML类图中箭头的含义
Explanation of the UML arrows Here's some explanations from the Visual Studio 2015 docs: UML Class D ...
- [转] Java中的final、static、this、super
final 关键字 final关键字主要用在三个地方:变量.方法.类. 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改:如果是引用类型的变量,则在对其初始化之后便 ...
- springBoot 全局异常捕捉
package cn.com.cs.core.exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import or ...