这不是技术问题,而是概念问题。我的程序需要在后台处理多项任务。就我而言,出于以下几个原因,我认为线程比进程更合适:
- 后台任务并不繁重,但必须定期处理。
- 所有线程都需要操作一个共享资源。完整的进程需要设置一个共享内存段,这在我的情况下不合适(资源没有固定大小)。当然,此资源受互斥体保护。
我考虑的另一件事是 main()
函数需要能够在需要时结束所有后台任务(这意味着加入线程)。
现在,这里有两个实现:
1 个线程,在内部循环。
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
,这可能很危险。
n个线程,向外循环。
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
上,它只需要终止它自己的连续循环(例如使用“ bool 值”)。
现在,我需要一些帮助来比较这两者。线程是轻量级结构,但是生成过程对于第二个实现来说是否过于繁重?还是无限循环在不应该的时候保持线程?目前,我更喜欢第二种实现,因为它保护了信号量:线程在 sem_post
之前不会终止。我关心的是优化,而不是功能。
最佳答案
让你的后台线程不断地产生和死亡往往是低效的。让一定数量的线程保持事件状态通常要好得多,以便在后台工作可用时为其提供服务。
但是,通常最好也避免线程取消。相反,我建议使用条件变量和退出标志:
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()
和 pthread_cond_init()
设置条件变量使用的时钟。)
关于c - 线程,定期生成 VS。陷入无限临时循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21801791/