我有一个工作线程进行轮询活动(它的目标是 libcurl,但这不相关)。
应用程序的许多操作都可以启动工作线程,但如果它已经在运行,则不应创建新线程。来自应用程序的新请求只需与任何其他正在进行的轮询相结合。
总之,当无事可做时退出的单个工作线程。
代码是:
pthread_t thread = NULL;
struct timespec sleep_val = {0, 20000000};
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_exit(NULL);
thread = NULL;
}
void start_worker_thread_if_needed() {
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
}
我怀疑线程安全。函数 start_worker_thread_if_needed() 可以在任何时间任意多次调用。
那么,如果 start_worker_thread_if_needed() 恰好在我们退出 while 循环并因此中断工作线程时被调用怎么办。如果发生这种情况,条件 if (thread == NULL) 将为 FALSE,因为工作线程被中断并且 pthread_exit + thread = NULL 尚未完成。
所以现在 start_worker_thread_if_needed() 将退出而不创建新线程,但是一旦控制权返回到旧的工作线程,它将继续到 pthread_exit 行并且工作线程被销毁。
问题将是刚刚触发 start_worker_thread_if_needed() 的请求将丢失,并且轮询将在下一次调用 start_worker_thread_if_needed() 之前开始。
编辑:这是一个关于互斥锁的建议,但我仍然有同样的疑问。如果主线程在我们退出 while 循环之后和 worker 可以获取互斥锁之前中断会发生什么。然后主线程不创建新线程然后worker退出。
void *worker_thread(void *threadid)
{
do {
poll();
nanosleep(&sleep_val, NULL);
} while (no_of_handles_running > 0);
pthread_mutex_lock(&my_mutex);
thread = NULL;
pthread_mutex_unlock(&my_mutex);
pthread_exit(NULL);
}
void start_worker_thread_if_needed() {
pthread_mutex_lock(&my_mutex);
if (thread == NULL) {
pthread_create(&thread, NULL, worker_thread, NULL);
}
pthread_mutex_unlock(&my_mutex);
}
我认为我的设置方式存在缺陷,如果有人可以提供正确的解决方案,我将不胜感激。