pthread 条件变量是否只能使用一次?
Is a pthread condition variable one time use only?
我正在学习使用 pthreads、互斥锁和条件变量,但事情没有按预期进行。
主线程: 连续运行,向工作线程发出信号,从 file_A.
读取
工作线程: 休眠直到收到信号,写入 file_A,返回休眠(应该是可重复的)
所以我知道这里需要一个互斥体来防止两个线程reading/writing进出同一个文件。我正在使用条件变量向工作线程发送信号。
但由于某种原因,工作线程只运行一次。我需要重置条件变量还是做其他事情?
工作线程函数:
void* WriteTime(){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condition, &mutex);
/* Open File, Write to File, Close File */
pthread_mutex_unlock(&mutex);
}
主线程:
pthread_t timeThread;
pthread_create(&timeThread, NULL, &WriteTime, NULL);
while(gameConditionFulfilled == false){
/* Print status, gets user input into line */
/* If user enters "time", wake up WORKER_THREAD */
if(strcmp(line, "time")==0){
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* Read from file, print data, close file */
pthread_mutex_unlock(&mutex);
}
}
另外我对上面代码的理解是这样的:
- 工作线程锁定互斥量。 (在 main 循环之前启动)
- 工作线程cond_wait解锁互斥量并等待条件。
- 主线程锁定互斥量。
- 主线程信号条件。
- 工作线程重新获得互斥锁,写入文件。
- 工作线程解锁互斥量。
- 主线程重新获得互斥量并锁定它。
- 主线程读取文件。
- 主线程解锁互斥。
- 工作线程重新获得锁?
实际行为是:
- 主线程从文件读取
- 工作线程唤醒,写入文件,不再运行
首先,您需要在 WriteTime() 中进行某种循环——returning 导致 pthread_exit() 被调用。当 pthread_create() 启动一个线程时,它的启动就像:
pthread_exit((*func)(arg));
这引出了第二点——你的编译器应该就此向你尖叫,因为你的 WriteTime() 没有 return 任何东西。警告很有用;它们不需要被遵守,但你应该明白它们为什么会出现。
略过几章,条件变量的概念是保护“条件”;例如,有数据准备好读取或写入。您像使用信号量一样使用它们,但与信号量不同的是,条件变量没有任何内存。 Pthread_condition_wait() 只会 return 如果 pthread_condition_(signal|broadcast)() 在线程等待时被调用。如果在没有人等待时调用 pthread_condition_signal(),则什么也不会发生。所以条件变量的惯用法是:
lock(mutex)
while (something_hasn’t_happened) {
wait(cond, mutex)
}
do something
unlock(mutex)
我正在学习使用 pthreads、互斥锁和条件变量,但事情没有按预期进行。
主线程: 连续运行,向工作线程发出信号,从 file_A.
读取工作线程: 休眠直到收到信号,写入 file_A,返回休眠(应该是可重复的)
所以我知道这里需要一个互斥体来防止两个线程reading/writing进出同一个文件。我正在使用条件变量向工作线程发送信号。
但由于某种原因,工作线程只运行一次。我需要重置条件变量还是做其他事情?
工作线程函数:
void* WriteTime(){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condition, &mutex);
/* Open File, Write to File, Close File */
pthread_mutex_unlock(&mutex);
}
主线程:
pthread_t timeThread;
pthread_create(&timeThread, NULL, &WriteTime, NULL);
while(gameConditionFulfilled == false){
/* Print status, gets user input into line */
/* If user enters "time", wake up WORKER_THREAD */
if(strcmp(line, "time")==0){
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* Read from file, print data, close file */
pthread_mutex_unlock(&mutex);
}
}
另外我对上面代码的理解是这样的:
- 工作线程锁定互斥量。 (在 main 循环之前启动)
- 工作线程cond_wait解锁互斥量并等待条件。
- 主线程锁定互斥量。
- 主线程信号条件。
- 工作线程重新获得互斥锁,写入文件。
- 工作线程解锁互斥量。
- 主线程重新获得互斥量并锁定它。
- 主线程读取文件。
- 主线程解锁互斥。
- 工作线程重新获得锁?
实际行为是:
- 主线程从文件读取
- 工作线程唤醒,写入文件,不再运行
首先,您需要在 WriteTime() 中进行某种循环——returning 导致 pthread_exit() 被调用。当 pthread_create() 启动一个线程时,它的启动就像:
pthread_exit((*func)(arg));
这引出了第二点——你的编译器应该就此向你尖叫,因为你的 WriteTime() 没有 return 任何东西。警告很有用;它们不需要被遵守,但你应该明白它们为什么会出现。
略过几章,条件变量的概念是保护“条件”;例如,有数据准备好读取或写入。您像使用信号量一样使用它们,但与信号量不同的是,条件变量没有任何内存。 Pthread_condition_wait() 只会 return 如果 pthread_condition_(signal|broadcast)() 在线程等待时被调用。如果在没有人等待时调用 pthread_condition_signal(),则什么也不会发生。所以条件变量的惯用法是:
lock(mutex)
while (something_hasn’t_happened) {
wait(cond, mutex)
}
do something
unlock(mutex)