linux c编程——条件变量

linux条件变量

条件变量变量也是出自POSIX线程标准,另一种线程同步机制,。主要用来等待某个条件的发生。可以用来同步同一进程中的各个线程。当然如果一个条件变量存放在多个进程共享的某个内存区中,那么还可以通过条件变量来进行进程间的同步。

每个条件变量总是和一个互斥量相关联,条件本身是由互斥量保护的,线程在改变条件状态之间必须要锁住互斥量。条件变量相对于互斥量最大的优点在于允许线程以无竞争的方式等待条件的发生。当一个线程获得互斥锁后,发现自己需要等待某个条件变为真,如果是这样,该线程就可以等待在某个条件上,这样就不需要通过轮询的方式来判断添加,大大节省了CPU时间。

例子(一个生产者,一个消费者)

条件变量是一种类似操作系统里提到的生产者-消费者算法的同步机制,允许线程以无竞争的方式等待特定条件的发生。

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int beginnum = 1000;

typedef struct _ProdInfo{
    int num;
    struct _ProdInfo *next;
}ProdInfo;

ProdInfo *Head = NULL;

void *thr_producter(void *arg){
    //负责在链表添加数据
    while (1)
    {
        ProdInfo * prod = malloc(sizeof(ProdInfo));
        prod->num = beginnum++;
        printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
        pthread_mutex_lock(&mutex);
        //add to list
        prod->next = Head;
        Head = prod;
        pthread_mutex_unlock(&mutex);
        //发起通知
        pthread_cond_signal(&cond);
        sleep(rand()%4);
    }
    return NULL;
}

void *thr_customer(void *arg){
    ProdInfo * prod = NULL;
    while (1)
    {
        //取链表的数据
        pthread_mutex_lock(&mutex);
        while(Head == NULL){
            pthread_cond_wait(&cond,&mutex);//在此之前必须先加锁
        }
        prod = Head;
        Head = Head->next;
        printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
        pthread_mutex_unlock(&mutex);
        sleep(rand()%4);
        free(prod);
    }
    return NULL;
}

int main(int argc, char const *argv[])
{
    pthread_t tid[2];
    pthread_create(&tid[0],NULL,thr_producter,NULL);
    pthread_create(&tid[1],NULL,thr_customer,NULL);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

输出

----thr_producter----self=140037231408896----1000
----thr_customer----self=140037223016192----1000
----thr_producter----self=140037231408896----1001
----thr_customer----self=140037223016192----1001
----thr_producter----self=140037231408896----1002
----thr_producter----self=140037231408896----1003
----thr_customer----self=140037223016192----1003
----thr_customer----self=140037223016192----1002
----thr_producter----self=140037231408896----1004
----thr_customer----self=140037223016192----1004
----thr_producter----self=140037231408896----1005
----thr_customer----self=140037223016192----1005
----thr_producter----self=140037231408896----1006
----thr_customer----self=140037223016192----1006
----thr_producter----self=140037231408896----1007

例子2(一个生产者,多个消费者)

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

int beginnum = 1000;

typedef struct _ProdInfo{
    int num;
    struct _ProdInfo *next;
}ProdInfo;

ProdInfo *Head = NULL;

void *thr_producter(void *arg){
    //负责在链表添加数据
    while (1)
    {
        ProdInfo * prod = malloc(sizeof(ProdInfo));
        prod->num = beginnum++;
        printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
        pthread_mutex_lock(&mutex);
        //add to list
        prod->next = Head;
        Head = prod;
        pthread_mutex_unlock(&mutex);
        //发起通知
        pthread_cond_signal(&cond);
        sleep(rand()%4);
    }
    return NULL;
}

void *thr_customer(void *arg){
    ProdInfo * prod = NULL;
    while (1)
    {
        //取链表的数据
        pthread_mutex_lock(&mutex);
        while(Head == NULL){
            pthread_cond_wait(&cond,&mutex);//在此之前必须先加锁
        }
        prod = Head;
        Head = Head->next;
        printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
        pthread_mutex_unlock(&mutex);
        sleep(rand()%4);
        free(prod);
    }
    return NULL;
}

int main(int argc, char const *argv[])
{
    pthread_t tid[2];
    pthread_create(&tid[0],NULL,thr_producter,NULL);
    pthread_create(&tid[1],NULL,thr_customer,NULL);
    pthread_create(&tid[2],NULL,thr_customer,NULL);

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
    pthread_join(tid[2],NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

参考

Linux线程同步之条件变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值