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;
    }
  • 相关阅读:
    redis 笔记04 服务器、复制
    redis 笔记03 RDB 持久化、AOF持久化、事件、客户端
    redis 笔记02 对象、数据库
    反射复习笔记02
    攻防世界 — Web进阶题(第11
    机器学习-极大似然和对数几率回归(浅入)
    redis的过期策略和内存淘汰
    Backbone.Router实践
    Spring Boot 数据访问
    Archives: 2018/12
  • 原文地址:https://www.cnblogs.com/whuqin/p/4982006.html
Copyright © 2011-2022 走看看