【发布时间】:2012-06-26 08:10:26
【问题描述】:
我有以下经理工人情况:
class Manager {
private:
pthread_attr_t workerSettings;
pthread_t worker;
pthread_cond_t condition;
pthread_mutex_t mutex;
bool workerRunning;
static void* worker_function(void* args) {
Manager* manager = (Manager*)args;
while(true) {
while(true) {
pthread_mutex_lock(&manager->mutex);
if(/* new data available */)
{
/* copy new data from shared to thread memory */
pthread_mutex_unlock(&manager->mutex);
}
else
{
pthread_mutex_unlock(&manager->mutex);
break;
}
/* process the data in thread memory */
pthread_mutex_lock(&manager->mutex);
/* copy results back to shared memory */
pthread_mutex_unlock(&manager->mutex);
}
pthread_mutex_lock(&manager->mutex);
// wait for new data to arrive
while(manager->workerRunning && !/* new data available*/)
pthread_cond_wait(&manager->condition, &manager->mutex);
// check if we should continue running
if(!manager->workerRunning)
{
pthread_mutex_unlock(&manager->mutex);
break;
}
pthread_mutex_unlock(&manager->mutex);
}
pthread_exit(NULL);
return NULL; // just to avoid the missing return statement compiler warning
}
public:
Manager() : workerRunning(true) {
pthread_cond_init(&condition, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&workerSettings);
pthread_attr_setdetachstate(&workerSettings, PTHREAD_CREATE_JOINABLE);
pthread_create(&worker, &workerSettings, worker_function, (void*)this);
}
// this *may* be called repeatedly or very seldom
void addData(void) {
pthread_mutex_lock(&mutex);
/* copy new data into shared memory */
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
}
~Manager()
{
// set workerRunning to false and signal the worker
pthread_mutex_lock(&mutex);
workerRunning = false;
pthread_cond_signal(&condition);
pthread_mutex_unlock(&mutex);
// wait for the worker to exit
pthread_join(worker, NULL);
// cleanup
pthread_attr_destroy(&workerSettings);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition);
}
};
我在几个地方对此并不完全确定:
- Manager 在其构造函数中生成一个新线程这一事实是否被认为是一种不好的做法? (我只会有一个 Manager 对象,所以我想应该没问题)
- pthread_exit 怎么样 - 我在很多教程中都看到了这个,但我不太明白为什么它应该在那里?我不能简单地返回函数以退出线程吗?我也认为返回 NULL 是死代码,但是 gcc 在它丢失时会发出警告,因为它显然不知道 pthread_exit 已经在那个时候杀死了线程。
- 关于构造函数 - 我可以在生成线程后立即销毁线程属性对象(workerSettings)还是必须在线程的整个生命周期内保持有效?
- 关于析构函数:这是正确的方法吗?
最重要的是:
- 您有经验的眼睛是否发现那里有任何同步问题?
感谢您的帮助!
【问题讨论】:
-
关于你的第二点,是的,从一个线程返回就足够了。你真的不需要
pthread_exit,除非你需要例如从被调用函数中退出线程。 -
好的,谢谢。我缺少任何释放吗?我不喜欢 pthread_t 对象在任何地方都没有被破坏的事实。
-
它应该被
pthread_join调用“销毁”。 -
忙等待永远不行,而且不清楚这段代码的预期目的是什么。为什么你希望工人在调用
pthread_join之前进入某种特定状态? -
我希望工作线程挂在 pthread_cond_wait 调用中,否则它可能会错过信号并导致死锁(工作线程挂在 pthread_cond_wait 中,主线程挂在 pthread_join 中)编辑:我想我可以添加在 pthread_cond_wait 调用之前的另一个 if(workerRunning) 来解决这个问题..
标签: c++ synchronization pthreads backgroundworker