互斥锁和条件变量

作用

互斥锁用于确保关键资源在修改时只有一个操作者
条件变量类似银行的叫号,协调各个操作者的操作顺序.当前一个操作者操作完成时,叫正在等待的下一个操作者前来操作.
在不引入条件变量之前,互斥锁会使其它线程处于空等状态,不断进行锁状态的检查.条件变量引入后,使相关的其它线程处于睡眠状态,当前操作者完成操作后再唤醒处于睡眠状态的线程.

基本函数

#include <pthread.h>
//互斥锁
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_trylock(pthread_mutex_t *mptr);
int pthread_mutex_unlock(pthread_mutex_t *mptr);
 
//条件变量
int pthread_cont_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cont_signal(pthread_cond_t *cptr);
 
//初始化与销毁
int pthread_mutex_init(pthread_mutex_t *mptr,const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mptr);
PTHREAD_MUTEX_INITIALIZER
int pthread_cond_init(pthread_cond_t *cptr,const pthread_condattr_t *attr);
int pthread_cond_destroy(pthread_cond_t *cptr);
PTHREAD_COND_INITIALIZER

例子

创建<#nthreads>个tid_produce线程, 生产<#nitems>个产品,每个线程生产出一个就通知consume线程
每个线程生产的总数记录在count[i]中, put结构中的nput记录当前所有线程已经生产的总数

#include "unpipc.h"
#include <pthread.h>
 
#define MAXITEMS 1000000
#define MAXTHREADS 100
#define min(a,b) a>b?b:a
 
int nitems;
int buff[MAXITEMS];
struct {
    pthread_mutex_t mutex;
    int nput;
    int nval;
} put= {
    PTHREAD_MUTEX_INITIALIZER
};
struct {
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    int nready;
} nready= {
    PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER
};
 
void *produce(void *), *consume(void *);
 
int main(int argc, char *argv[]){
    int i,nthreads,count[MAXTHREADS];
    pthread_t tid_produce[MAXTHREADS],tid_consume;
 
    if(argc != 3)
        err_quit("usage: lock <#items> <#threads>");
    nitems=min(atoi(argv[1]),MAXITEMS);
    nthreads=min(atoi(argv[2]),MAXTHREADS);
 
    pthread_setconcurrency(nthreads+1);
 
    pthread_create(&tid_consume,NULL,consume,NULL);
    for(i=0;i<nthreads;++i){
        count[i]=0;
        pthread_create(&tid_produce[i],NULL,produce,&count[i]);
    }
 
    for(i=0;i<nthreads;++i){
        pthread_join(tid_produce[i],NULL);
        printf("in main: count[%d]=%d
",i,count[i]);
    }
 
    pthread_join(tid_consume,NULL);
    return 0;
}
 
void *
produce(void *arg){
    for(;;){
        pthread_mutex_lock(&put.mutex);
        if(put.nput >= nitems){
            pthread_mutex_unlock(&put.mutex);
            return(NULL);
        }
        buff[put.nput] = put.nval;
        put.nput++;
        put.nval++;
        pthread_mutex_unlock(&put.mutex);
 
        pthread_mutex_lock(&nready.mutex);
        if(nready.nready == 0)
            pthread_cond_signal(&nready.cond);
        nready.nready++;
        pthread_mutex_unlock(&nready.mutex);
        *((int *)arg) += 1;  //count[i] += 1
    }
}
 
void *
consume(void *arg){
    int i;
    for(i=0;i<nitems;++i){
        pthread_mutex_lock(&nready.mutex);
        while(nready.nready == 0)
            pthread_cond_wait(&nready.cond,&nready.mutex);
        nready.nready--;
        pthread_mutex_unlock(&nready.mutex);
 
        if(buff[i] != i)
            printf("buff[%d] = %d
",i,buff[i]);
    }
    return NULL;
}
原文地址:https://www.cnblogs.com/cfans1993/p/5793760.html