线程,定期生成VS.在无限的临时循环陷阱?

时间:2014-02-15 18:30:39

标签: c multithreading optimization pthreads

这不是一个技术问题,而是一个概念问题。我的程序需要在后台处理几个任务。就我而言,我认为线程比流程更合适有几个原因:

  • 后台任务并不重,但必须定期处理。
  • 所有线程都需要操纵共享资源。完整的流程需要设置共享内存段,这在我的情况下是不合适的(资源没有固定的大小)。当然,此资源受互斥锁保护。

我要考虑的另一件事是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上,它只需要杀死自己的连续循环(使用&# 34;布尔"例如)。

现在,我想帮助比较这两者。线程是轻量级结构,但是第二次实现的产生过程太重了吗?或者是无限循环持有线程时它应该不是吗?目前,我更喜欢第二种实现,因为它保护信号量:线程在它们sem_post之前不会终止。我关注的是优化,而不是功能。

1 个答案:

答案 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}}设置条件变量使用的时钟。)