用条件变量(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;
}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值