线程间使用条件变量同步正确方式

来源:互联网 发布:数据库报表开发帆软 编辑:程序博客网 时间:2024/04/29 10:23

线程间同步标准的使用方式如下:

//thread 1://    pthread_mutex_lock(&mutex);//    while (!condition)//          pthread_cond_wait(&cond, &mutex);//    func_1();  /* do something that requires holding the mutex and condition is true *///    pthread_mutex_unlock(&mutex);//thread2://    pthread_mutex_lock(&mutex);//    func_2();  /* do something that might make condition true *///    pthread_cond_signal(&cond);//    pthread_mutex_unlock(&mutex);

关于条件变量使用的一些陷阱参照:http://www.cppblog.com/Solstice/archive/2013/09/09/203094.html
------------------------------------------------------------------------------------------------------
  pthread_cond_signal():  唤醒等待cond的线程
  pthread_cond_wait():     释放mutex 睡眠等待cond条件发生,pthread_cond_wait()通常和mutex绑定在
                                        一起. 在pthread_cond_wait中,为保证信号不会丢失 释放mutex和进入cond的
                                        等待队列是原子的操作. 当线程收到信号时在wakeup前需要重新获得mutex. 如果
                                        发送线程还没有释放mutex,则当前线程继续等待直到获得mutex该函数才返回.
------------------------------------------------------------------------------------------------------

简单实现一个线程安全队列:

template <class T>class Queue{private:pthread_cond_t cond;pthread_mutex_t mutex;std::queue<T> items;public:Queue();~Queue();bool empty();int size();int push(const T item);int pop(T *data);};template <class T>Queue<T>::Queue(){pthread_cond_init(&cond, NULL);pthread_mutex_init(&mutex, NULL);}template <class T>Queue<T>::~Queue(){pthread_cond_destroy(&cond);pthread_mutex_destroy(&mutex);}template <class T>bool Queue<T>::empty(){bool ret = false;if(pthread_mutex_lock(&mutex) != 0){return -1;}ret = items.empty();pthread_mutex_unlock(&mutex);return ret;}template <class T>int Queue<T>::size(){int ret = -1;if(pthread_mutex_lock(&mutex) != 0){return -1;}ret = items.size();pthread_mutex_unlock(&mutex);return ret;}template <class T>int Queue<T>::push(const T item){if(pthread_mutex_lock(&mutex) != 0){return -1;}{items.push(item);}pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond);return 1;}template <class T>int Queue<T>::pop(T *data){if(pthread_mutex_lock(&mutex) != 0){return -1;}{while(items.empty()){if(pthread_cond_wait(&cond, &mutex) != 0){return -1;}}*data = items.front();items.pop();}if(pthread_mutex_unlock(&mutex) != 0){return -1;}return 1;}


0 0
原创粉丝点击