zoukankan      html  css  js  c++  java
  • 【linux高级程序设计】(第十二章)Linux多线程编程 3

    条件变量通信机制

    条件变量必须配合互斥锁一起实现对资源的互斥访问

    使用方法:

    int pthread_cond_init (pthread_cond_t *__restrict __cond, __const pthread_condattr_t *__restrict __cond_attr) :初始化条件变量,第二个参数是属性对象,NULL为默认

    int pthread_cond_destroy (pthread_cond_t *__cond)销毁条件变量

    int pthread_cond_signal (pthread_cond_t *__cond)通知等待条件变量的第一个线程,如果没有等待线程,则不起作用

    int pthread_cond_broadcast (pthread_cond_t *__cond)通知等待的条件变量的所有线程,如果没有等待线程,则不起作用

    int pthread_cond_wait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex)等待条件变量,第二个参数指向于条件变量关联的互斥锁指针

    int pthread_cond_timewait (pthread_cond_t *__restrict __cond, pthread_mutex_t *__restrict __mutex, __const struct timespec *__restrict __abstime) :在指定时间内等待条件变量

    在线程因等待条件变量进入等待状态时,将释放其申请的互斥锁。在等到条件变量时,会隐含申请到该互斥锁              

    条件变量实现读写锁

    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #include "pthread.h"
    #define BUFFER_SIZE 2
    //条件信息结构体
    struct prodcons
    {
        int buffer[BUFFER_SIZE];  //生产产品值
        pthread_mutex_t lock;     //互斥锁
        int readpos, writepos;    //读写位置
        pthread_cond_t notempty;  //条件变量,表非空
        pthread_cond_t notfull;   //条件变量,表非满
    };
    
    //初始化
    void init(struct prodcons *prod)
    {
        pthread_mutex_init(&prod->lock, NULL);
        pthread_cond_init(&prod->notempty, NULL);
        pthread_cond_init(&prod->notfull, NULL);
        prod->readpos = 0;
        prod->writepos = 0;
    }
    
    //在缓冲区输入一个数据
    void put(struct prodcons * prod, int data)
    {
        //锁定互斥锁
        pthread_mutex_lock(&prod->lock);
        while((prod->writepos + 1) % BUFFER_SIZE == prod->readpos) //测试是否空间已满  注意 这里writepos的位置要加1 即保证下一个写入的位置是空的 ??
        {
            printf("producer wait for not full
    ");
            pthread_cond_wait(&prod->notfull, &prod->lock); //等待有空间写
        }
        //写数据
        prod->buffer[prod->writepos] = data;
        prod->writepos++;
        if(prod->writepos >= BUFFER_SIZE)
            prod->writepos = 0;
        pthread_cond_signal(&prod->notempty);
        pthread_mutex_unlock(&prod->lock);
    }
    
    //从缓冲区读一个数据
    int get(struct prodcons * prod)
    {
        int data;
        //锁定互斥锁
        pthread_mutex_lock(&prod->lock);
        while(prod->writepos == prod->readpos)
        {
            printf("producer wait for not empty
    ");
            pthread_cond_wait(&prod->notempty, &prod->lock); 
        }
        data = prod->buffer[prod->readpos];
        prod->readpos++;
        if(prod->readpos >= BUFFER_SIZE)
            prod->readpos = 0;
        pthread_cond_signal(&prod->notfull);
        pthread_mutex_unlock(&prod->lock);
        return data;
    }
    
    #define OVER (-1)
    struct prodcons buffer;
    
    //生产者
    void * producer(void * data)
    {
        int n;
        for(n = 1; n <= 5; n++) //生产5个产品
        {
            printf("producer sleep 1 second...
    ");
            sleep(1);
            printf("put the %d product
    ", n);
            put(&buffer, n);
        }
        for(n = 6; n <= 10; n++)
        {
            printf("producer sleep 3 second...
    ");
            sleep(3);
            printf("put the %d product
    ", n);
            put(&buffer, n);
        }
        put(&buffer, OVER);
        printf("producer stopped!
    ");
        return NULL;
    }
    
    //消费者
    void * consumer(void * data)
    {
        int d = 0;
        while(1)
        {
            printf("consumer sleep 2 second...
    ");
            sleep(2);
            d = get(&buffer);
            printf("get the %d product
    ", d);
            if(d == OVER)
                break;
        }
        printf("consumer stopped!
    ");
        return NULL;
    }
    
    int main(int argc, char *argv[])
    {
        pthread_t th_a, th_b;
        void * retval;
        init(&buffer);
        pthread_create(&th_a, NULL, producer, 0);
        pthread_create(&th_b, NULL, consumer, 0);
        pthread_join(th_a, &retval);
        pthread_join(th_b, &retval);
        return 0;
    }

    验证,可用

  • 相关阅读:
    android原子
    android进程优先级
    Android 的cyclicBarrier
    android中运用CountDownLatch
    java网络编程长连接的问题
    https
    http 上传文件
    netty4 断线重连
    Linux下高并发socket最大连接数所受的各种限制
    Android Studio NDK及so文件开发
  • 原文地址:https://www.cnblogs.com/dplearning/p/4690466.html
Copyright © 2011-2022 走看看