Linux 线程 条件变量
//等待条件
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex); :把调用线程放到所等待条件的线程列表上
:对传进来已经加过锁的互斥量解锁
:线程进入休眠状态等待被唤醒
注:、2步为原子操作 //通知条件
int pthread_cond_signal(pthread_cond_t *cond); :通知指定条件已经满足
:等待线程重新锁定互斥锁
:等待线程需要重新测试条件是否满足
#include <iostream>
#include <queue>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h> using std::cout;
using std::endl;
using std::queue; #define N 100
#define ST 10 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ready = PTHREAD_COND_INITIALIZER; queue<int> que; void* threadProducer(void* arg)
{
while(true)
{
sleep(rand() % ST); cout << "Produce try in...\n";
pthread_mutex_lock(&lock);
cout << "Produce in!\n";
int source = rand() % N;
cout << "Produce " << source << endl;
que.push(source);
pthread_mutex_unlock(&lock);
cout << "Produce out\n"; pthread_cond_signal(&ready);
}
} void* threadConsumer(void* arg)
{
while(true)
{
sleep(rand() % ST); cout << "Consum try in...\n";
pthread_mutex_lock(&lock);
cout << "Consum in!\n";
while(que.empty())
{
pthread_cond_wait(&ready, &lock);
cout << "Consum from sleep\n";
}
cout << "Consum " << que.front() << endl;
que.pop();
pthread_mutex_unlock(&lock);
cout << "Consum out\n\n";
}
} int main(void)
{
pthread_t tProducer, tConsumer;
pthread_create(&tProducer, NULL, threadProducer, NULL);
pthread_create(&tConsumer, NULL, threadConsumer, NULL); pthread_join(tProducer, NULL);
pthread_join(tConsumer, NULL); exit();
}
生消

看到倒数的三四行,消费者进去了,发现没有数据了,则睡眠了,然后生产者进去生产了。
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h> using std::cout;
using std::endl; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ready = PTHREAD_COND_INITIALIZER; int data = ; void* threadProducer(void* arg)
{
int i;
for(i = ; i < ; i++)
{
sleep(); if(i % != )
{
cout << "thread1:" << i << endl;
}
else
{
pthread_mutex_lock(&lock);
data = i;
pthread_mutex_unlock(&lock); pthread_cond_signal(&ready);
}
}
} void* threadConsumer(void* arg)
{
while(true)
{
pthread_mutex_lock(&lock);
while(data == ) //no data
pthread_cond_wait(&ready, &lock);
cout <<"thread2:" << data << endl;
if(data == )
break;
else
data = ; //empty data
pthread_mutex_unlock(&lock);
}
} int main(void)
{
pthread_t tProducer, tConsumer;
pthread_create(&tProducer, NULL, threadProducer, NULL);
pthread_create(&tConsumer, NULL, threadConsumer, NULL); pthread_join(tProducer, NULL);
pthread_join(tConsumer, NULL); exit();
}
3打印

程序大致这样:线程1中的循环,如果i不是3的倍数就自己打印了,如果是的话,把这个数放到一个地方(由于这个地方可以被线程2发现,所以要加锁访问),然后唤醒等待数据的线程2(如果线程2还没有在等待,那么这个唤醒则丢失,这是个bug,见下),线程2被唤醒后,消费了这个3的倍数,清空数据区。
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h> using std::cout;
using std::endl; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ready = PTHREAD_COND_INITIALIZER; int data = ; void* threadProducer(void* arg)
{
int i;
for(i = ; i < ; i++)
{
sleep(); if(i % != )
{
cout << "thread1:" << i << endl;
}
else
{
pthread_mutex_lock(&lock);
data = i;
pthread_mutex_unlock(&lock); pthread_cond_signal(&ready);
}
}
} void* threadConsumer(void* arg)
{
sleep();
while(true)
{
pthread_mutex_lock(&lock);
while(data == ) //no data
pthread_cond_wait(&ready, &lock);
cout <<"thread2:" << data << endl;
if(data == )
break;
else
data = ; //empty data
pthread_mutex_unlock(&lock);
}
} int main(void)
{
pthread_t tProducer, tConsumer;
pthread_create(&tProducer, NULL, threadProducer, NULL);
pthread_create(&tConsumer, NULL, threadConsumer, NULL); pthread_join(tProducer, NULL);
pthread_join(tConsumer, NULL); exit();
}
bug

//下面是生产者 pthread_mutex_lock(&lock); //加锁访问临界区
/*在这里生产数据*/
pthread_mutex_unlock(&lock); //解锁 pthread_cond_signal(&ready); //通知消费者 //下面是消费者 pthread_mutex_lock(&lock); //加锁访问临界区
while(没有待消费数据)
pthread_cond_wait(&ready, &lock); //睡在这里,等待被唤醒
/*被叫醒了,在这里消费数据*/
pthread_mutex_unlock(&lock); //解锁
Linux 线程 条件变量的更多相关文章
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- Linux Posix线程条件变量
生产者消费者模型 .多个线程操作全局变量n,需要做成临界区(要加锁--线程锁或者信号量) .调用函数pthread_cond_wait(&g_cond,&g_mutex)让这个线程锁在 ...
- Linux 多线程条件变量同步
条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的 ...
- Linux:条件变量
条件变量: 条件变量本身不是锁!但它也可以造成线程阻塞.通常与互斥锁配合使用.给多线程提供一个会合的场所. 主要应用函数: pthread_cond_init函数 pthrea ...
- 笔记3 linux 多线程 条件变量+互斥锁
//cond lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test { ...
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...
- linux 互斥锁和条件变量
为什么有条件变量? 请参看一个线程等待某种事件发生 注意:本文是linux c版本的条件变量和互斥锁(mutex),不是C++的. mutex : mutual exclusion(相互排斥) 1,互 ...
- Linux 线程管理
解析1 LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数.但这个函数的执行过程比较难于理解. pthread_cond_wait()的工 ...
- c++ 条件变量
.条件变量创建 静态创建:pthread_cond_t cond=PTHREAD_COND_INITIALIZER; 动态创建:pthread_cond _t cond; pthread_cond_i ...
随机推荐
- redhat的启动方式和执行次序
rc.d的内容如下: init.d/ :各种服务器和程序的二进制文件存放目录. rcx.d/: 各个启动级别的执行程序连接目录.里头的东西都是指向init.d/的一些软连接.具体的后边叙述. 还有三个 ...
- Android开发目录
1.ADT下载地址整理 2.之前的Android项目报错,新建Android项目报错,代码中找不到错误解决方案 3.错误“Unexpected namespace prefix "xmlns ...
- Jquery实现文本框获取焦点清空内容,失去焦点重新获得内容的公共函数
最近在做一个同城交友网站你给我吧(www.niyuewo.com)时写的一个函数与大家分享: //清除input中的内容 $(document).ready(function(){ $("i ...
- 9款基于CSS3 Transitions实现的鼠标经过图标悬停特效
之前给大家分享了很多css3实现的按钮特效.今天给大家分享9款基于CSS3 Transitions实现的鼠标经过图标悬停特效.这款特效适用浏览器:360.FireFox.Chrome.Safari.O ...
- android studio无法更新之解决方案
当发现android studio有更新时,当然第一时间就想更新,可惜被墙了. 解决方案: 下载wallproxy,百度你懂的 在proxy.ini中最上面,找到ip和port 接着,在android ...
- CSS 之 控制图片与文字对齐
文字旁边搭配图片时,发现图片比文字靠上,原来默认的情况是图片顶对齐而文字底对齐,通过设置css属性可以使得图片与文字对齐. 设置各对象的vertical-align属性,属性说明: baseline- ...
- Saving HDU
Problem Description 话说上回讲到海东集团面临内外交困,公司的元老也只剩下XHD夫妇二人了.显然,作为多年拼搏的商人,XHD不会坐以待毙的. 一天,当他正在苦思冥想解困良策的时候, ...
- solr安全-tomcat
1.1. tomcat部署1 参考文档:solr安全机制 1.1.1. 加上安全机制的必要性 在前面有提到, Solr 本身是不加安全机制的, 所有的查詢.admin.update 這些指令都可以經由 ...
- android 布局之滑动探究 scrollTo 和 scrollBy 方法使用说明
涉及到滑动,就涉及到VIEW,大家都知道,Android的UI界面都是由一个一个的View以及View的派生类组成,View作为基类,而常用的布局里面的各种布局就是它派生出来的ViewGroup的子类 ...
- nodejs学习第一天
//按照nodejs文档上第一页的例子敲了一遍运行了 迷茫 先这样吧 慢慢来 const http = require('http'); const host = '127.0.0.1'; const ...