微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在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()函数

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐