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;
}

 

posted @ 2013-07-09 14:49  春文秋武  阅读(455)  评论(0编辑  收藏  举报