zoukankan      html  css  js  c++  java
  • Linux多线程系列-2-条件变量的使用(线程安全队列的实现)

    多线程情况下,往往需要使用互斥变量来实现线程间的同步,实现资源正确共享。

    linux下使用如下变量和函数

    //条件变量
    pthread_cond_t
    int pthread_cond_init (pthread_cond_t *c, const pthread_condattr_t *a)
    int pthread_cond_wait (pthread_cond_t *c, pthread_mutex_t *m)
    int pthread_cond_timedwait (pthread_cond_t *c,pthread_mutex_t *m, const struct timespec *t)
    int pthread_cond_signal (pthread_cond_t *c)
    int pthread_cond_destroy (pthread_cond_t *c)
    
    //互斥变量
    pthread_mutex_t 
    int pthread_mutex_init (pthread_mutex_t *m, const pthread_mutexattr_t *a)
    int pthread_mutex_lock(pthread_mutex_t *m)
    int pthread_mutex_unlock(pthread_mutex_t *m)
    int pthread_mutex_destroy (pthread_mutex_t *m)


    利用条件变量和互斥变量来实现一个互斥队列

    #include <pthread.h>
    const int SIZE = 100;
    const int NUM = 200;
    class MyQueue{
    public:
        MyQueue():head(0),tail(0){
            //变量初始化
            pthread_mutex_init(&mutex, NULL);
            pthread_cond_init(&notempty, NULL);
            pthread_cond_init(&notfull, NULL);
        }
        void push(int i);
        int pop();
        ~MyQueue(){
            pthread_mutex_destroy(&mutex);
            pthread_cond_destroy(&notempty);
            pthread_cond_destroy(&notfull);
        }
    
    private:
        bool is_full() {
          return (tail + 1) % SIZE == head;
        }
        bool is_empty() {
          return tail == head;
        }
    
    private:
        int buf[SIZE];
        int head;
        int tail;
        pthread_mutex_t mutex;   //互斥使用锁
        pthread_cond_t notempty; //非空条件变量
        pthread_cond_t notfull;  //队列不满条件变量
    
    };
    
    //尾部插入元素
    void MyQueue::push(int i) {
        pthread_mutex_lock(&mutex);
        while (is_full()) {
            cout << "queue is full, wait" << endl;
            pthread_cond_wait(&notfull, &mutex);
        }
        buf[tail] = i;
        tail = (tail + 1) % SIZE;
        //通知等待notempty的线程,队列不空
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&notempty);
    }
    
    //头部取元素
    int MyQueue::pop() {
        pthread_mutex_lock(&mutex);
        while (is_empty()) {
            cout << "queue is empty, wait" << endl;
            pthread_cond_wait(&notempty, &mutex);
        }
        int i = buf[head];
        head = (head + 1) % SIZE;
        //通知等待notfull的线程,队列不满
        pthread_mutex_unlock(&mutex);
        pthread_cond_signal(&notfull);
        return i;
    }
    
    void* producer(void* args) {
        MyQueue* queue = (MyQueue*)args;
        for (int i = 0; i < NUM; ++i) {
            queue->push(i);
            cout << "push:" << i << endl;
        }
    }
    void* consumer(void* args) {
        MyQueue* queue = (MyQueue*)args;
        for (int i = 0; i < NUM; ++i) {
            cout << "pop:" << queue->pop() << endl;
        }
    }
    int main() {
        MyQueue queue;
    
        pthread_t pro_thread;
        pthread_t con_thread;
        pthread_create(&pro_thread, NULL, producer, &queue);
        pthread_create(&con_thread, NULL, consumer, &queue);
        
        pthread_join(pro_thread, NULL);
        pthread_join(con_thread, NULL);
        cout << "End" << endl;
    }
  • 相关阅读:
    图像处理之优化---任意半径局部直方图类算法在PC中快速实现的框架
    新的验证方式---短信验证和语言验证
    习武 之路---通背拳和苗刀!
    模式识别之Shape Context---利用Shape Context进行形状识别
    ELK 部署
    rsync实现文件备份同步
    oracle-3-子查询和常用函数
    oracle-2中commit 详解
    使用nginx绑定域名,代理gitlab
    Linux Crontab 安装使用详细说明
  • 原文地址:https://www.cnblogs.com/whuqin/p/4982006.html
Copyright © 2011-2022 走看看