スレッド間で条件変数を使用して同期する正しい方法
2616 ワード
スレッド間同期基準の使用方法は次のとおりです.
条件変数で使用されるトラップ参照について: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を取得するまで待機し続け、その関数が返される.
//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 Queue{
private:
pthread_cond_t cond;
pthread_mutex_t mutex;
std::queue items;
public:
Queue();
~Queue();
bool empty();
int size();
int push(const T item);
int pop(T *data);
};
template
Queue::Queue(){
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
}
template
Queue::~Queue(){
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
}
template
bool Queue::empty(){
bool ret = false;
if(pthread_mutex_lock(&mutex) != 0){
return -1;
}
ret = items.empty();
pthread_mutex_unlock(&mutex);
return ret;
}
template
int Queue::size(){
int ret = -1;
if(pthread_mutex_lock(&mutex) != 0){
return -1;
}
ret = items.size();
pthread_mutex_unlock(&mutex);
return ret;
}
template
int Queue::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
int Queue::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;
}