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(¬empty, NULL); pthread_cond_init(¬full, NULL); } void push(int i); int pop(); ~MyQueue(){ pthread_mutex_destroy(&mutex); pthread_cond_destroy(¬empty); pthread_cond_destroy(¬full); } 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(¬full, &mutex); } buf[tail] = i; tail = (tail + 1) % SIZE; //通知等待notempty的线程,队列不空 pthread_mutex_unlock(&mutex); pthread_cond_signal(¬empty); } //头部取元素 int MyQueue::pop() { pthread_mutex_lock(&mutex); while (is_empty()) { cout << "queue is empty, wait" << endl; pthread_cond_wait(¬empty, &mutex); } int i = buf[head]; head = (head + 1) % SIZE; //通知等待notfull的线程,队列不满 pthread_mutex_unlock(&mutex); pthread_cond_signal(¬full); 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; }