用条件变量(Condition Variable)实现信号量(Semaphore)
用条件变量(Condition Variable)实现信号量(Semaphore),
主要是通过条件变量控制资源数的加减操作,在这里定义sem_t 为
struct sem{
int num;
pthread_mutex_t lock;
pthread_cond_t cond;
};
资源数由num决定,当num为0时应用条件变量让线程挂起,直到条件满足之后再次获取资源。
void sem_init(sem_t * semm, int num) 初始化函数,定义资源数。
void sem_wait(sem_t * semm) 获取资源,获得资源后,资源数-1,未获得资源则挂起等待,
这里需要注意的一点是,pthread_cond_wait在挂起等待的时候是不会占用互斥锁(mutex),
进而能保证sem_post对num的操作不被挂起。
void sem_post(sem_t * semm) 释放资源,资源数+1;
代码如下:
//"semaphore_xx.h"
#ifndef SEMAPHORE_XX_20121008
#define SEMAPHORE_XX_20121008
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
namespace sem_xx{
struct sem{
int num;
pthread_mutex_t lock;
pthread_cond_t cond;
};
typedef struct sem sem_t;
void sem_init(sem_t * semm, int num){
semm->num = num;
pthread_mutex_init(&(semm->lock), NULL);
pthread_cond_init(&(semm->cond), NULL);
}
void sem_wait(sem_t * semm){
pthread_mutex_lock(&(semm->lock));
while ( semm->num == 0)
pthread_cond_wait(&(semm->cond), &(semm->lock));
semm->num--;
pthread_mutex_unlock(&(semm->lock));
}
void sem_post(sem_t * semm){
pthread_mutex_lock(&(semm->lock));
/*fuck! Here is a stupid mistake!Just add the num will be ok!!
Otherwise,we will be blocked here!
while ( semm->num == 0)
pthread_cond_wait(&(semm->cond), &(semm->lock));
*/
semm->num++;
pthread_mutex_unlock(&(semm->lock));
pthread_cond_signal(&(semm->cond));
}
}
#endif
利用上面代码实现生产者-消费者模式:
代码如下:
//"test.cpp"
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
//#include <semaphore.h>
#include "semaphore_xx.h"
#define NUM 5
int queue[NUM];
using namespace sem_xx;
sem blank_number, product_number;
void *producer(void *arg)
{
int p = 0;
while (1) {
sem_wait(&blank_number);
queue[p] = rand() % 1000 + 1;
printf("Produce %d\n", queue[p]);
sem_post(&product_number);
p = (p+1)%NUM;
sleep(rand()%5);
}
}
void *consumer(void *arg)
{
int c = 0;
while (1) {
sem_wait(&product_number);
printf("Consume %d\n", queue[c]);
queue[c] = 0;
sem_post(&blank_number);
c = (c+1)%NUM;
sleep(rand()%5);
}
}
int main(int argc, char *argv[])
{
pthread_t pid, cid;
sem_init(&blank_number, NUM);
sem_init(&product_number, 0);
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
---------------------
作者:jungxiangyi
原文:https://blog.csdn.net/jungxiangyi/article/details/8049472
用条件变量(Condition Variable)实现信号量(Semaphore)相关推荐
- 对条件变量(condition variable)的讨论
作者:王东 1.1 什么是条件变量和条件等待? 简单的说: 条件变量(condition variable)是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个 ...
- 条件变量(condition variable)详解
原理: 假设我们需要解决这样一个问题:一个列表记录需要处理的任务.一个线程往此列表添加任务,一个线程processTask处理此列表中的任务.这个问题的一个关键点在于processTask怎么判断任务 ...
- c++11 多线程编程(六)------条件变量(Condition Variable)
互斥锁std::mutex是一种最常见的线程间同步的手段,但是在有些情况下不太高效. 假设想实现一个简单的消费者生产者模型,一个线程往队列中放入数据,一个线程往队列中取数据,取数据前需要判断一下队列中 ...
- c++11多线程编程同步——使用条件变量condition variable
简述 在多线程编程中,当多个线程之间需要进行某些同步机制时,如某个线程的执行需要另一个线程完成后才能进行,可以使用条件变量. c++11提供的 condition_variable 类是一个同步原语, ...
- linux条件变量使用和与信号量的区别
linux条件变量使用和与信号量的区别 今天在学习进程同步机制的时候看见一句话: 条件变量只能在管程中通过两个原语操作--wait原语和signal原语 于是发出了一个疑问:信号量机制和条件变量同步机 ...
- python 线程超时设置_python 条件变量Condition(36)
文章首发微信公众号,微信搜索:猿说python 对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – ...
- Python 线程条件变量 Condition - Python零基础入门教程
目录 一.Python 线程条件变量 Condition 函数 二.Python 线程条件变量 Condition 原理 三.Python 线程条件变量 Condition 使用 四.Python 线 ...
- 用C++ 封装linux下的互斥锁MutexLock和条件变量Condition
/*封装互斥锁的时候,要用到的方法,20200605*/ //问题一:MutexLock和Condition是否要设计成单例模式? // 单例模式只能通过该类创建出一个对象,这意味着只能创建一把锁,如 ...
- 互斥量、条件变量与pthread_cond_wait()函数的使用,详解(二)
互斥量.条件变量与pthread_cond_wait()函数的使用,详解(二) 1.Linux"线程" 进程与线程之间是有区别的,不过linux内核只提供了轻量进程的支持,未实现线 ...
- 【Python】条件变量、信号变量、事件
条件变量.信号变量.事件 信号量:信号量是用来解决线程同步和互斥的通用工具, 和互斥量类似, 信号量也可以用作于资源互斥访问, 但信号量没有所有者的概念,在应用上比互斥量更广泛,信号量比较简单, 不能 ...
最新文章
- 《Create Your Successful Agile Project》书评与作者访谈
- 用ipython 写spark
- uni-app 微信小程序自定义radio样式
- Jersey注解详解
- springboot+安卓app电子阅览室系统毕业设计源码016514
- unef螺纹_螺纹标准大全
- mathtype服务器不显示,出现MathType字体无效的情况怎么办
- KVM/QEMU(virt-manager)使用iso镜像安装macOS bigsur 11.4
- Android简单制作自定义圆形头像
- (D)TLS1.3大揭秘之TLS1.3总体概览
- MoviePy合成视频没有声音
- Python模糊匹配 | 刷英语六级段落匹配只需要3秒?
- zedboard运行linux,(转载)一步一步学ZedBoard Zynq(六):在ZedBoard上运行linux并编写linux下的应用程序HelloWorld...
- py: pip3老,导致安装 flask avatar 依赖的 pillow 安装不上
- java串口读取数据设置超时时间,附详细答案
- SAS中保留t值、F值和Z值的三位小数
- java aes加密 base64_【java】AES加密解密|及Base64的使用
- Blender渲染崩溃原因汇总,如何解决渲染崩溃情况?
- egret的eui.List滚动
- excel找到对应数据的列指标_三种方式制作数据地图
热门文章
- 卫士处刑者冠军css3边,天赋升华_流放之路3.9卫士流血BD_3.9冠军流血弓刷图BD攻略_3DM网游...
- 2.3Linux常用命令
- 苹果计算机能打出分数吗,Apple M1芯片安兔兔跑分曝光:分数打破安兔兔记录
- 眼动数据中瞳孔大小这个数据怎么用?
- NJ 时钟自动调整功能(SNTP)
- [记录] JavaScript 中的正则表达式
- 交换机/路由器的存储介质
- 1024分辨率《X战警:第一战》BD中英双字无水印
- LVGL开发|lv_lib_100ask之lvgl中文输入(lv_100ask_pinyin_ime )-LVGL中文输入
- css水墨背景,PS古风水墨背景教程