用条件变量(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)相关推荐

  1. 对条件变量(condition variable)的讨论

    作者:王东 1.1       什么是条件变量和条件等待? 简单的说: 条件变量(condition variable)是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个 ...

  2. 条件变量(condition variable)详解

    原理: 假设我们需要解决这样一个问题:一个列表记录需要处理的任务.一个线程往此列表添加任务,一个线程processTask处理此列表中的任务.这个问题的一个关键点在于processTask怎么判断任务 ...

  3. c++11 多线程编程(六)------条件变量(Condition Variable)

    互斥锁std::mutex是一种最常见的线程间同步的手段,但是在有些情况下不太高效. 假设想实现一个简单的消费者生产者模型,一个线程往队列中放入数据,一个线程往队列中取数据,取数据前需要判断一下队列中 ...

  4. c++11多线程编程同步——使用条件变量condition variable

    简述 在多线程编程中,当多个线程之间需要进行某些同步机制时,如某个线程的执行需要另一个线程完成后才能进行,可以使用条件变量. c++11提供的 condition_variable 类是一个同步原语, ...

  5. linux条件变量使用和与信号量的区别

    linux条件变量使用和与信号量的区别 今天在学习进程同步机制的时候看见一句话: 条件变量只能在管程中通过两个原语操作--wait原语和signal原语 于是发出了一个疑问:信号量机制和条件变量同步机 ...

  6. python 线程超时设置_python 条件变量Condition(36)

    文章首发微信公众号,微信搜索:猿说python 对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – ...

  7. Python 线程条件变量 Condition - Python零基础入门教程

    目录 一.Python 线程条件变量 Condition 函数 二.Python 线程条件变量 Condition 原理 三.Python 线程条件变量 Condition 使用 四.Python 线 ...

  8. 用C++ 封装linux下的互斥锁MutexLock和条件变量Condition

    /*封装互斥锁的时候,要用到的方法,20200605*/ //问题一:MutexLock和Condition是否要设计成单例模式? // 单例模式只能通过该类创建出一个对象,这意味着只能创建一把锁,如 ...

  9. 互斥量、条件变量与pthread_cond_wait()函数的使用,详解(二)

    互斥量.条件变量与pthread_cond_wait()函数的使用,详解(二) 1.Linux"线程" 进程与线程之间是有区别的,不过linux内核只提供了轻量进程的支持,未实现线 ...

  10. 【Python】条件变量、信号变量、事件

    条件变量.信号变量.事件 信号量:信号量是用来解决线程同步和互斥的通用工具, 和互斥量类似, 信号量也可以用作于资源互斥访问, 但信号量没有所有者的概念,在应用上比互斥量更广泛,信号量比较简单, 不能 ...

最新文章

  1. 《Create Your Successful Agile Project》书评与作者访谈
  2. 用ipython 写spark
  3. uni-app 微信小程序自定义radio样式
  4. Jersey注解详解
  5. springboot+安卓app电子阅览室系统毕业设计源码016514
  6. unef螺纹_螺纹标准大全
  7. mathtype服务器不显示,出现MathType字体无效的情况怎么办
  8. KVM/QEMU(virt-manager)使用iso镜像安装macOS bigsur 11.4
  9. Android简单制作自定义圆形头像
  10. (D)TLS1.3大揭秘之TLS1.3总体概览
  11. MoviePy合成视频没有声音
  12. Python模糊匹配 | 刷英语六级段落匹配只需要3秒?
  13. zedboard运行linux,(转载)一步一步学ZedBoard Zynq(六):在ZedBoard上运行linux并编写linux下的应用程序HelloWorld...
  14. py: pip3老,导致安装 flask avatar 依赖的 pillow 安装不上
  15. java串口读取数据设置超时时间,附详细答案
  16. SAS中保留t值、F值和Z值的三位小数
  17. java aes加密 base64_【java】AES加密解密|及Base64的使用
  18. Blender渲染崩溃原因汇总,如何解决渲染崩溃情况?
  19. egret的eui.List滚动
  20. excel找到对应数据的列指标_三种方式制作数据地图

热门文章

  1. 卫士处刑者冠军css3边,天赋升华_流放之路3.9卫士流血BD_3.9冠军流血弓刷图BD攻略_3DM网游...
  2. 2.3Linux常用命令
  3. 苹果计算机能打出分数吗,Apple M1芯片安兔兔跑分曝光:分数打破安兔兔记录
  4. 眼动数据中瞳孔大小这个数据怎么用?
  5. NJ 时钟自动调整功能(SNTP)
  6. [记录] JavaScript 中的正则表达式
  7. 交换机/路由器的存储介质
  8. 1024分辨率《X战警:第一战》BD中英双字无水印
  9. LVGL开发|lv_lib_100ask之lvgl中文输入(lv_100ask_pinyin_ime )-LVGL中文输入
  10. css水墨背景,PS古风水墨背景教程