【Go 语言社区】Go语言条件变量的两个例子
时间:2022-05-04
本文章向大家介绍【Go 语言社区】Go语言条件变量的两个例子,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在Go语言中 sync.Cond 代表条件变量,但它需要配置锁才能有用.
var m Mutex
c := NewCond(&m)
或 c := sync.NewCond(&sync.RWMutex{}) 之类. 它有三个函数: wait/signal/broadcast 望文知义,和Windows下的InitializeConditionVariable与WaitForSingleObject()之类, 及Linux下的pthread_cond_t等作用差不多.
弄了两个例子:
/*
条件变量 Cond 例子
Author: xcl
Date: 2015-11-29
*/
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func main() {
runtime.GOMAXPROCS(4)
test333()
}
func testCond() {
c := sync.NewCond(&sync.Mutex{})
condition := false
go func() {
time.Sleep(time.Second * 1)
c.L.Lock()
fmt.Println("[1] 变更condition状态,并发出变更通知.")
condition = true
c.Signal() //c.Broadcast()
fmt.Println("[1] 继续后续处理.")
c.L.Unlock()
}()
c.L.Lock()
fmt.Println("[2] condition..........1")
for !condition {
fmt.Println("[2] condition..........2")
//等待Cond消息通知
c.Wait()
fmt.Println("[2] condition..........3")
}
fmt.Println("[2] condition..........4")
c.L.Unlock()
fmt.Println("main end...")
}
/*
testCond()运行结果:
[2] condition..........1
[2] condition..........2
[1] 变更condition状态,并发出变更通知.
[1] 继续后续处理.
[2] condition..........3
[2] condition..........4
main end...
*/
复制代码
例二
/*
条件变量 Cond 例子
Author: xcl
Date: 2015-11-29
*/
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
const MAX_CLIENTS = 3
func main() {
runtime.GOMAXPROCS(4)
testCond()
}
func testCond() {
s := NewServer()
go s.IOloop()
time.Sleep(time.Second * 1)
go func() {
s.Release()
}()
go func() {
s.Release()
}()
time.Sleep(time.Second * 1)
s.Release()
time.Sleep(time.Second * 1)
fmt.Println("[testCond] end.")
}
type Server struct {
clients uint64
cond *sync.Cond
}
func NewServer() *Server {
s := &Server{}
s.cond = sync.NewCond(&sync.Mutex{})
return s
}
func (s *Server) IOloop() {
for {
s.cond.L.Lock()
for s.clients == MAX_CLIENTS {
fmt.Println("[IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release()")
s.cond.Wait()
}
s.cond.L.Unlock()
s.clients++
fmt.Println("[IOloop] clients:", s.clients)
}
}
func (s *Server) Release() {
s.cond.L.Lock()
s.clients--
fmt.Println("[Release] a clients:", s.clients)
s.cond.Signal()
fmt.Println("[Release] b clients:", s.clients)
s.cond.L.Unlock()
}
/*
运行结果:
[IOloop] clients: 1
[IOloop] clients: 2
[IOloop] clients: 3
[IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release()
[Release] a clients: 2
[Release] b clients: 2
[Release] a clients: 1
[Release] b clients: 1
[IOloop] clients: 2
[IOloop] clients: 3
[IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release()
[Release] a clients: 2
[Release] b clients: 2
[IOloop] clients: 3
[IOloop] 等于MAX_CLIENTS了,等待Cond通知.即有触发Release()
[testCond] end.
*/
对于条件变量和channl,知乎有个问答很精彩,可以看看: http://www.zhihu.com/question/27256570
另外 <<Go语言并发编程>>中也有个同一时间多个Goroutine分别进行对一个文件进行读写操作的例子也很精彩,直观。
噢,对了,附上C++11条件变量的使用例子:
// condition_variable example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck);
// ...
std::cout << "thread " << id << 'n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all();
}
int main ()
{
std::thread threads[10];
// spawn 10 threads:
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);
std::cout << "10 threads ready to race...n";
go(); // go!
for (auto& th : threads) th.join();
return 0;
}
- 漫谈Java IO之 Netty与NIO服务器
- Java线程的几种状态
- POJ3683 Priest John's Busiest Day(2-SAT)
- javascript 面向对象(实现继承的几种方式)
- Base64 的 JavaScript 实现 js-base64
- HTTP请求详解
- 漫谈Java IO之 NIO那些事儿
- 1593: [Usaco2008 Feb]Hotel 旅馆
- BZOJ 1823: [JSOI2010]满汉全席(2-SAT)
- 3360: [Usaco2004 Jan]算二十四
- JavaScript 数据类型
- 3361: [Usaco2004 Jan]培根距离
- Java NIO
- 1342: [Baltic2007]Sound静音问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 用Python的Pandas和Matplotlib绘制股票唐奇安通道,布林带通道和鳄鱼组线
- Java的Covariance设计原理和SAP ABAP的模拟实现
- ABAP和Java的tag(marker) interface
- setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制
- 使用ABAP的RTTI和Java反射机制访问static private属性
- ABAP面试问题 - 不使用加减乘除等操作比较两个整数大小
- SAP订单上Shipping抬头和行项目字段的持久化实现原理
- SAP CRM订单模型CRMD_SHIPPING的单元测试方法
- 给SAP WebClient UI的表格行项目增添PDF预览功能
- 如何将ABAP透明表的内容导入PostgreSQL数据库
- 使用代理模式改善SAP UI5应用的图片加载体验
- 如何使用ABAP open SQL的locator
- dotnet 新 SDK Style 项目格式如何使用 InternalsVisibleToAttribute 功能
- WPF dotnet core 如何开启 Pointer 消息的支持
- web Storage的特点