如何在pthread中终止睡眠线程?

我有长时间睡觉的线程,然后醒来做些事情,然后再睡觉,像这样:

while(some_condition) { // do something sleep(1000); }

我怎样才能让这个线程优雅地退出,很快?

我试图使用pthread_cancel() ,但睡眠线程无法取消。 我也尝试改变while循环的条件,但是它仍然需要很长时间才能退出。 而且我不想使用pthread_kill() ,因为它可能会在线程工作时终止。

那么,有什么好主意吗?

当我尝试在Linux上使用64位perl的DBD :: Advantage时,为什么会出现“Error 6060”?

如何在ANSI C中使用glDrawVertex()函数

使用期望脚本的多个文件自动化SCP

在linux中检查函数库中是否存在

bash – 无条件布尔expression式评估

奇怪的错误与setsockopt,“协议不可用”

指定在Linux上启动可执行文件时要使用的dynamic链接器/加载器

一个Linux命令复制/replace“横幅”命令?

与螺纹的叉和核心转储

GCC安装错误

作为sleep的替代方法,您可以使用超时时间为1000毫秒的pthread_cond_timedwait 。 然后当你想退出时,发信号给条件变量。

这与您在C#/ Java中如何使用wait和notify可以做到这一点类似。

经典的UNIX条件变量是自我管道 。

int fds[2]; pipe2(fds,O_NONBLOCK); // requires newish kernel and glibc; use pipe + 2*fcntl otherwise child: while (some_condition) { // do something struct pollfd pd = { .fd = fds[0],.events = POLLIN }; int rc; char c; while ((rc = poll(&pd,1,1000000)) == -1 && errno == EINTR) // not entirely correct; 1000000 should be decreased according to elapsed time when repeating after a signal interruption ; if (rc > 0 && (pd.revents & POLLIN) && read(fds[0],&c,1) >= 0) break; } parent: cancel() { char c = 0; write(fds[1],1); }

是的,这是很多(和未经测试的)代码。 你应该使用pthread_cond_wait ,它需要一个pthread_mutex_t和一个pthread_cond_t但是要容易得多。

你用pthread_cleanup_push和pop吗? 没有它们,使用pthread_cancel取消不起作用。 你必须成对使用它们,就像我在下面的例子中一样。 如果你忘了它不会编译(花式宏,一个有'{',另一个有'}')。 你甚至可以嵌套不同级别的清理/弹出。 无论如何,他们设置了一个跳远点,当取消发生时取消跳转(非常酷)。 此外,如果您的测试程序不等待线程启动或停止,您可能不会注意到取消发生。

例:

#include <stdio.h> #include <stdlib.h> #include <pthread.h> static void *ThreadProc(void * arg); static void unwind(__attribute__ ((unused)) void *arg); int _fActive = 0; int main(int argc,char** argv) { pthread_t Thread; int nRet; nRet = pthread_create(&Thread,NULL,ThreadProc,NULL); printf("MAIN: waiting for thread to startup...n"); while (_fActive == 0) nanosleep(&(struct timespec){ 0,0},NULL); printf("MAIN: sending cancel...n"); nRet = pthread_cancel(Thread); printf("MAIN: waiting for thread to exit...n"); while (_fActive) nanosleep(&(struct timespec){ 0,NULL); printf("MAIN: donen"); return 0; } static void unwind(__attribute__ ((unused)) void *arg) { // do some cleanup if u want printf("THREAD: unwind (all threads,canceled or normal exit get here)n"); _fActive = 0; } static void *ThreadProc(void * arg) { pthread_cleanup_push(unwind,arg); // optional : pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); printf("THREAD: Enter Sleepn"); _fActive = 1; sleep(1000000); printf("THREAD: Exit Sleep (canceled thread never gets here)n"); pthread_cleanup_pop(1); printf("THREAD: Exit (canceled thread never gets here)n"); return NULL; }

节目输出

MAIN: waiting for thread to startup... THREAD: Enter Sleep MAIN: sending cancel... MAIN: waiting for thread to exit... THREAD: unwind (all threads,canceled or normal exit get here) MAIN: done

注意取消点sleep()中的ThreadProc是如何取消的,只执行unwind()函数

相关文章

本篇内容主要讲解“gitee如何上传代码”,感兴趣的朋友不妨来...
这篇“从gitee上下的代码如何用”文章的知识点大部分人都不太...
这篇文章主要介绍“gitee如何下载仓库里的项目”,在日常操作...
本篇内容主要讲解“怎么在Gitee上更新代码”,感兴趣的朋友不...
本文小编为大家详细介绍“怎么将工程托管到gitee”,内容详细...
这篇文章主要介绍了gitee中图片大小如何调整的相关知识,内容...