学习pthreads,使用条件变量进行多线程之间的同步
条件变量提供另一种多线程同步的方法。互斥量通过控制对共享数据的访问来同步任务。条件变量可以根据数据的值来同步任务。条件变量是当一个事件发生时发送信号的信号量。一旦事件发生,可能会有多个线程在等待信号,条件变量通常用于对操作的顺序进行同步。使用条件变量对多线程进行同步时,条件变量和互斥量得同时使用。知道这些大概知识,本文将重点探讨怎么使用条件变量进行同步,结构分为三个部分,第一部分给出代码示例,第二部分对代码进行讲解,第三部分给出运行结果。
一、代码示例
#include "StdAfx.h"
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define NUM_THREADS 3
#define TCOUNT 10
#define COUNT_LIMIT 12
int count = 0;
pthread_mutex_t count_mutex;
pthread_cond_t count_threshold_cv;
void *inc_count(void *t)
{
int i;
long my_id = (long)t;
for (i=0; i < TCOUNT; i++) {
pthread_mutex_lock(&count_mutex);
count++;
/*
Check the value of count and signal waiting thread when condition is
reached. Note that this occurs while mutex is locked.
*/
if (count == COUNT_LIMIT) {
printf("inc_count(): thread %ld, count = %d Threshold reached. ",
my_id, count);
pthread_cond_signal(&count_threshold_cv);
printf("Just sent signal.\n");
}
printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
my_id, count);
pthread_mutex_unlock(&count_mutex);
/* Do some work so threads can alternate on mutex lock */
Sleep(10);
}
pthread_exit(NULL);
return(NULL);
}
void *watch_count(void *t)
{
long my_id = (long)t;
printf("Starting watch_count(): thread %ld\n", my_id);
/*
Lock mutex and wait for signal. Note that the pthread_cond_wait routine
will automatically and atomically unlock mutex while it waits.
Also, note that if COUNT_LIMIT is reached before this routine is run by
the waiting thread, the loop will be skipped to prevent pthread_cond_wait
from never returning.
*/
pthread_mutex_lock(&count_mutex);
while (count < COUNT_LIMIT) {
printf("watch_count(): thread %ld Count= %d. Going into wait...\n", my_id,count);
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received. Count= %d\n", my_id,count);
printf("watch_count(): thread %ld Updating the value of count...\n", my_id,count);
count += 125;
printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
}
printf("watch_count(): thread %ld Unlocking mutex.\n", my_id);
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
return(NULL);
}
int main(int argc, char *argv[])
{
int i, rc;
long t1=1, t2=2, t3=3;
pthread_t threads[3];
pthread_attr_t attr;
/* Initialize mutex and condition variable objects */
pthread_mutex_init(&count_mutex, NULL);
pthread_cond_init (&count_threshold_cv, NULL);
/* For portability, explicitly create threads in a joinable state */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, watch_count, (void *)t1);
pthread_create(&threads[1], &attr, inc_count, (void *)t2);
pthread_create(&threads[2], &attr, inc_count, (void *)t3);
/* Wait for all threads to complete */
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf ("Main(): Waited and joined with %d threads. Final value of count = %d. Done.\n",
NUM_THREADS, count);
/* Clean up and exit */
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&count_mutex);
pthread_cond_destroy(&count_threshold_cv);
pthread_exit (NULL);
}
二、代码讲解
int count = 0; pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv;
定义全局变量计数器,互斥量和条件变量
void *inc_count(void *t)
{
int i;
long my_id = (long)t;
for (i=0; i < TCOUNT; i++) {
pthread_mutex_lock(&count_mutex);
count++;
if (count == COUNT_LIMIT) {
printf("inc_count(): thread %ld, count = %d Threshold reached. ",
my_id, count);
pthread_cond_signal(&count_threshold_cv);
printf("Just sent signal.\n");
}
printf("inc_count(): thread %ld, count = %d, unlocking mutex\n",
my_id, count);
pthread_mutex_unlock(&count_mutex);
Sleep(10);
}
pthread_exit(NULL);
return(NULL);
}
inc_count()函数是线程2和3执行的任务,每次for循环调用pthread_mutex_lock锁住互斥量,从而对全局变量进行计数,当计数达到一定条件,调用pthread_cond_signal函数发送条件变量,然后对互斥量进行解锁,为了另一个线程有充足时间锁住互斥量,让本线程休眠一段时间,最后退出线程。
void *watch_count(void *t)
{
long my_id = (long)t;
printf("Starting watch_count(): thread %ld\n", my_id);
pthread_mutex_lock(&count_mutex);
while (count < COUNT_LIMIT) {
printf("watch_count(): thread %ld Count= %d. Going into wait...\n", my_id,count);
pthread_cond_wait(&count_threshold_cv, &count_mutex);
printf("watch_count(): thread %ld Condition signal received. Count= %d\n", my_id,count);
printf("watch_count(): thread %ld Updating the value of count...\n", my_id,count);
count += 125;
printf("watch_count(): thread %ld count now = %d.\n", my_id, count);
}
printf("watch_count(): thread %ld Unlocking mutex.\n", my_id);
pthread_mutex_unlock(&count_mutex);
pthread_exit(NULL);
return(NULL);
}
watch_count函数是线程1执行的函数,该线程主要是完成接受发送的条件变量。首先,调用pthread_mutex_lock函数锁住互斥量我;为了使等待时间在有限范围内,使用满足条件的while循环,因为假如count大于条件,那么等待的时间将是无穷无尽的;调用pthread_cond_wait函数接受条件变量,直到接受到条件变量,才执行下一步程序;接受完条件变量后,对互斥量进行解锁,最后退出线程。
int i, rc; long t1=1, t2=2, t3=3; pthread_t threads[3]; pthread_attr_t attr; pthread_mutex_init(&count_mutex, NULL); pthread_cond_init (&count_threshold_cv, NULL);
定义程序所需变量,pthread_t变量以及属性对象attr;初始化全局互斥量,初始化全局条件变量。
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threads[0], &attr, watch_count, (void *)t1);
pthread_create(&threads[1], &attr, inc_count, (void *)t2);
pthread_create(&threads[2], &attr, inc_count, (void *)t3);
for (i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf ("Main(): Waited and joined with %d threads. Final value of count = %d. Done.\n",
NUM_THREADS, count);
初始化属性对象,并将属性对象设置为可结合的,然后使用该属性对象创建三个线程,分别执行watch_count和inc_count函数,最后结合所有的线程。
pthread_attr_destroy(&attr); pthread_mutex_destroy(&count_mutex); pthread_cond_destroy(&count_threshold_cv); pthread_exit (NULL);
销毁属性对象、互斥量和条件变量,退出线程。
三、运行结果
学习pthreads,使用条件变量进行多线程之间的同步的更多相关文章
- 学习pthreads,创建和终止多线程
更CPU多线程编程,通过笔者的研究发现,,pthreads使用日趋广泛.它是螺纹POSIX标准,它定义了一组线程的创建和操作API. 配置环境见上博客文章.配置环境后,只需要加入#include &l ...
- Linux Qt使用POSIX多线程条件变量、互斥锁(量)
今天团建,但是文章也要写.酒要喝好,文要写美,方为我辈程序员的全才之路.嘎嘎 之前一直在看POSIX的多线程编程,上个周末结合自己的理解,写了一个基于Qt的用条件变量同步线程的例子.故此来和大家一起分 ...
- 条件变量signal与unlock的顺序
编写同步队列时,有用到条件变量,对操作队列的线程进行同步.当队列为空时,允许get线程挂起,直到add线程向队列添加元素并通过唤醒条件变量,get线程继续向下运行.条件变量在多线程程序中用来实现“等待 ...
- linux线程同步(2)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
- boost库(条件变量)
1相关理念 (1)类名 条件变量和互斥变量都是boost库中被封装的类. (2)条件变量 条件变量是thread库提供的一种等待线程同步的机制,可实现线程间的通信,它必须与互斥量配合使用,等待另一个线 ...
- posix 条件变量与互斥锁 示例生产者--消费者问题
一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行. 在pthr ...
- linux条件变量
条件变量用于线程之间的通信,和互斥锁一起使用.条件变量用于及时通知等待的线程条件的变化,使线程不至于错过变化. 考虑下面的情况,有AB两个线程对index这个全局变量进行++,一个线程C用于判断,in ...
- c++11中的线程、锁和条件变量
void func(int i, double d, const string& s) { cout << i << ", " << d ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
随机推荐
- Node.js 逐行读取
逐行读取 稳定性: 2 - 不稳定 使用 require('readline'),可以使用这个模块.逐行读取(Readline)可以逐行读取流(比如process.stdin) 一旦你开启了这个模块, ...
- 用python爬了自己的微信,原来好友都是这样的!
偶然了解到Python里的itchat包,它已经完成了wechat的个人账号API接口,使爬取个人微信信息更加方便.鉴于自己很早之前就想知道诸如自己微信好友性别比例都来自哪个城市之类的问题,于是乎玩心 ...
- 介绍Docker仓库
仓库(Repository)是集中存放镜像的地方. 一个容易混淆的概念是注册服务器(Registry).实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像.从 ...
- WebRTC 音频算法 附完整C代码
WebRTC提供一套音频处理引擎, 包含以下算法: AGC自动增益控制(Automatic Gain Control) ANS噪音抑制(Automatic Noise Suppression) AEC ...
- Make things beautiful again !
在知乎有一个问题:如何让大脑休息放松? 我曾回答说:整理凌乱的文件夹(电脑的). 其实最近特别烦恼,似乎所有人都不按常理出牌,似乎所有事都不按套路发展.经营一个企业的压力,加上长期没有来自" ...
- hive表的存储格式; ORC格式的使用
hive表的源文件存储格式有几类: 1.TEXTFILE 默认格式,建表时不指定默认为这个格式,导入数据时会直接把数据文件拷贝到hdfs上不进行处理.源文件可以直接通过hadoop fs -cat 查 ...
- rbac数据库设计
1 rbac数据库设计 RBAC基于资源的访问控制(Resource-Based Access Control)是以资源为中心进行访问控制分享牛原创,分享牛系列,分享牛.rbac 用户角色权限资源表如 ...
- Swift:Minimizing Annotation with Type Inference
许多程序猿更喜欢比如Python和Javascript这样的动态语言,因为这些语言并不要求程序猿为每个变量声明和管理它们的类型. 在大多数动态类型的语言里,变量可以是任何类型,而类型声明是可选的或者根 ...
- Android Multimedia框架总结(十六)Camera2框架之openCamera及session过程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52942533 前言:前一篇介绍了 ...
- Python 函数参数传递机制.
learning python,5e中讲到.Python的函数参数传递机制是对象引用. Arguments are passed by assignment (object reference). I ...