这不是一个技术问题,而是一个概念问题。我的程序需要在后台处理几个任务。就我而言,我认为线程比流程更合适有几个原因:
我要考虑的另一件事是main()
函数需要能够在需要时结束所有后台任务(这意味着加入线程)。
现在,这里有两个实现:
void *my_thread_func(void* shared_ressource)
{
while(1){
do_the_job();
sleep(5);
}
}
// main()
pthread_create(&my_thread, NULL, my_thread_func, (void*)&shared_ressource);
pthread_kill(my_thread, 15);
// pthread_cancel(my_thread);
pthread_join(my_thread, NULL);
注意:在这种情况下,main()
需要在加入前发信号通知(或取消)线程,否则它会挂起。如果线程在终止之前没有时间到sem_post
,这可能会很危险。
void *my_thread_func(void* shared_ressource)
{
do_the_job();
}
// main()
while(1){
pthread_create(&my_thread, NULL, my_thread_func, (void*)&shared_ressource);
pthread_join(my_thread, NULL);
sleep(5);
}
注意:在这种情况下,main()
自然不会挂在pthread_join
上,它只需要杀死自己的连续循环(使用&# 34;布尔"例如)。
现在,我想帮助比较这两者。线程是轻量级结构,但是第二次实现的产生过程太重了吗?或者是无限循环持有线程时它应该不是吗?目前,我更喜欢第二种实现,因为它保护信号量:线程在它们sem_post
之前不会终止。我关注的是优化,而不是功能。
答案 0 :(得分:2)
让你的背景线程不断产生和死亡往往效率低下。让一些线程保持活跃状态通常要好得多,为后台工作提供服务。
但是,通常最好避免线程取消。相反,我建议使用条件变量并退出标志:
void *my_thread_func(void *shared_resource)
{
struct timespec timeout;
pthread_mutex_lock(&exit_mutex);
do
{
pthread_mutex_unlock(&exit_mutex);
do_the_job();
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += 5;
pthread_mutex_lock(&exit_mutex);
if (!exit_flag)
pthread_cond_timedwait(&exit_cond, &exit_mutex, &timeout);
} while (!exit_flag)
pthread_mutex_unlock(&exit_mutex);
}
当主线程想要后台线程退出时,它会设置退出标志并发出条件变量信号:
pthread_mutex_lock(&exit_mutex);
exit_flag = 1;
pthread_cond_signal(&exit_cond);
pthread_mutex_unlock(&exit_mutex);
pthread_join(my_thread, NULL);
(实际上,您应该强烈考虑使用CLOCK_MONOTONIC
而不是默认的CLOCK_REALTIME
,因为前者不受系统时钟更改的影响。这需要使用pthread_condattr_setclock()
和{{ 1}}设置条件变量使用的时钟。)