用条件变量(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. Netty 之 Zero-copy 的实现(下)
  2. 借用的对vue-cli配置对解析
  3. android8.1状态栏图标,Android 8.1 去掉 Launcher3 默认给 icon 增加的白边
  4. delphi php 加密解密_如何恢复被MaMoCrypt勒索软件加密的数据
  5. typora设置代码不自动换行
  6. 数据结构之红黑树简介
  7. BROTHER 废墨清零教学
  8. 64位x86微服务器芯片,卖贝商城告诉你微服务器替代x86服务器的利与弊
  9. 第二章 Python数据类型和运算符
  10. 【Linux集群教程】11 集群监控 - Zabbix 搭建
  11. linpack测试软件,linpack
  12. php 问号乱码,如何解决php问号乱码的问题
  13. 高德地图纠偏 php,高德地图开发中,缩放后Marker偏移的问题
  14. 展示数据的3大要点——web数据可视化的实现
  15. php 图片木马检测
  16. python xy 官网_pythonxy 安装
  17. 运维工程师是桥的护栏_海沧大桥护栏救过不少车 海沧大桥护栏如何养护
  18. python猜字游戏猜三次_python 猜字游戏
  19. python与c语言的区别-c语言和python之间有什么区别
  20. 制作“大白菜”启动U盘教程

热门文章

  1. 蓝翔开设电竞专业,从《英雄联盟》学起;360将借壳江南嘉捷登陆A股;苹果iPhone X首拆丨价值早报
  2. Oracle实现金额小写转大写函数
  3. go sync.Mutex
  4. swak4foam的安装(v7测试有效)
  5. 中海达ihand30手簿使用说明_中海达iHand30 手簿使用说明书
  6. 中英文全角半角括号转换
  7. 区块链+跨境支付的应用及案例分析
  8. 汉字转换为拼音的JavaScript库
  9. validation校验 @NotNull @NotBlank及分组校验
  10. 决策树,逻辑回归,PCA-算法面经