POSIX条件变量

1.什么是条件变量

  • 当一个线程互斥地访问某个变量的时候,它可能发现在其它线程改变状态之前,它什么也做不了
  • 例如一个线程访问队列时,发现对列为空,它只能等待,直到其它线程将一个节点添加到队列中。这种情况就需要条件变量。

2.条件变量函数

pthread_cond_init //初始化
pthread_cond_destroy //销毁
pthread_cond_wait //在一个条件之上等待
pthread_cond_signal //条件满足时向一个等待线程发起通知
pthread_cond_broadcast //向等待的所有线程发起通知

3.条件变量使用规范

  • 等待条件代码
pthread_mutex_lock(&mutex);
while (条件为假)//不用if是pthread_cond_wait可能被虚假唤醒
    pthread_cond_wait(cond, mutex);
修改条件
pthread_mutex_unlock(&mutex);
  • 给条件发送信号代码
pthread_mutex_lock(&mutex);
设置条件为真
pthread_cond_signal (cond);
pthread_mutex_unlock(&mutex);

4.条件变量解决生产者与消费者问题

#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#define ERR_EXIT(m) \
    do \
    { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while (0);


#define CONSUMERS_COUNT 2
#define PRODUCERS_COUNT 1

pthread_mutex_t g_mutex;
pthread_cond_t g_cond;

pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];

int nready = 0; //当前缓冲区产品个数

void* consume(void *arg)
{
    int num = *((int*)(&arg));
    while (1)
    {
        pthread_mutex_lock(&g_mutex);
        while (nready == 0)
        {
            printf("%d begin wait a condition ...\n", num);
            pthread_cond_wait(&g_cond, &g_mutex); //对g_mutex进行解锁操作,才能让其它线程对nready进行修改
        }
        
        printf("%d end wait a condition ...\n", num);
        printf("%d begin consume product ...\n", num);
        --nready;
        printf("%d end consume product ...\n", num);
        pthread_mutex_unlock(&g_mutex);
        sleep(1);
    }
    return NULL;
}

void* produce(void *arg)
{
    int num = *((int*)(&arg));
    while (1)
    {
        pthread_mutex_lock(&g_mutex);
        printf("%d begin produce product ...\n", num);
        ++nready;
        printf("%d end produce product ...\n", num);
        pthread_cond_signal(&g_cond);
        printf("%d signal\n", num);
        pthread_mutex_unlock(&g_mutex);
        sleep(5);
    }
    
    return NULL;
}

int main(void)
{
    pthread_mutex_init(&g_mutex, NULL);
    pthread_cond_init(&g_cond, NULL);

    int i;
    for (i=0; i<CONSUMERS_COUNT; i++)
    {
        pthread_create(&g_thread[i], NULL, consume, (void*)i);
    }

    sleep(1);

    for (i=0; i<PRODUCERS_COUNT; i++)
    {
        pthread_create(&g_thread[CONSUMERS_COUNT + i], NULL, produce, (void*)i);
    }

    for (i=0; i<CONSUMERS_COUNT + PRODUCERS_COUNT; i++)
    {
        pthread_join(g_thread[i], NULL);
    }
    
    pthread_mutex_destroy(&g_mutex);
    pthread_cond_destroy(&g_cond);
    return 0;
}
    

pthread_cond_wait(cond, mutex)详解

  • 对mutex进行解锁
  • 等待条件,直到有线程向它发起通知
  • 重新对mutex进行加锁操作

pthread_cond_signal(cond)详解

  • 向第一个等待条件的线程发起通知,如果没有任何一个线程处理等待条件的状态,这个通知将被忽略
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值