睡在线程中(C/POSIX线程)

Emr*_*ici 12 c multithreading sleep pthreads usleep

我正在开发一个使用POSIX线程的多线程应用程序.我正在使用线程来做一个定期的工作,为此我使用usleep(3)暂停线程执行.我的问题是如何从主线程取消usleep()计时器,我试过pthread_kill(thread, SIGALRM)但它具有全局效果,导致主应用程序终止(默认情况下).这是我的伪代码:

void threaded_task(void *ptr) {
    initialize();

    while(running) {
        do_the_work();
        usleep(some_interval);
    }

    clean_up();
    release_resources();
}
Run Code Online (Sandbox Code Playgroud)

这里是伪函数,用于从主线程停止(并正常关闭)给定线程:

void stop_thread(pthread_t thread) {
    set_running_state(thread, 0); // Actually I use mutex staff
    // TODO: Cancel sleep timer so that I will not wait for nothing.
    // Wait for task to finish possibly running work and clean up 
    pthread_join(thread, NULL);
}
Run Code Online (Sandbox Code Playgroud)

实现目标的便捷方式是什么?我是否必须使用条件变量,或者我可以使用sleep()变体吗?

Ign*_*ams 9

使用select()FIFO或插座,您可以戳它以唤醒它.


Pat*_*ter 6

你也可以用信号量睡觉(事实上它是真正的目的).

a sema_wait在你的主题和sema_post主线程中.它很简单,干净,便于携带.这里有一篇文章的链接,详细介绍了该过程:http: //www.netrino.com/node/202


nat*_*ose 5

SIGALRM杀死整个应用程序的原因是您可能没有为它注册信号处理程序.SIGALRM的默认操作是内核终止进程,因此如果usleep以不使用SIGALRM的方式实现(例如,使用nanosleep带有超时的轮询函数或其中一个轮询函数),则usleep不会注册处理程序或其他方式更改了信号的默认配置.

void handle_alrm(int sig) {
}

...

int main(void) {
    signal(SIGALRM, handle_alrm);
    ...
Run Code Online (Sandbox Code Playgroud)

尽管你应该考虑更复杂的sigaction功能而不是signal因为它允许更多控制并且在不同平台上表现得更加一致,所以应该足以避免杀死你的程序.

这可能会导致问题,如果你再尝试使用代码,不会使用SIGALRM实现系统上usleepsleep,所以你可能想只是没有使用这些标准库版本,并使用功能有跨所有平台更可预测的实现(可能是一个薄的包装器nanosleep,提供你想要的接口).

  • 根据POSIX,`sleep`或`usleep`与`SIGALRM`的实现是不一致的. (2认同)