zoukankan      html  css  js  c++  java
  • 互斥锁和条件变量

    作用

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

    基本函数

    #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;
    }
    
  • 相关阅读:
    oralce索引的使用
    oracle中connect by prior的使用
    oracle函数listagg使用
    oracle函数的使用
    redis高可用集群搭建
    Node.js安装及环境配置之Windows篇
    Repeater 合并单元格
    c#16进制转浮点数单精度类型
    EF Core 实体映射表或视图
    docker 构建filebeat镜像
  • 原文地址:https://www.cnblogs.com/cfans1993/p/5793760.html
Copyright © 2011-2022 走看看