我正在学习pthread_cancel函数,并testing当线程没有到达取消点时线程是否会被取消。 线程是由默认属性创build的,并使其在join循环中运行。 但是,当取消请求发送和线程立即退出。 它没有达到取消点,我认为它不应该立即回应请求。
#include <stdio.h> #include <pthread.h> #include <stdlib.h> void *thread_func(void *arg) { int i; int j; int k; k = 1; /* add operation */ for (i=0; i<1000; ++i) { for (j=0; j<10000;++j) { ++k; // maybe for(z=0; z<10000; ++z) added would // be better } } return (void *)10; } int main(void) { char *retval; pthread_t tid; if (pthread_create(&tid, NULL, thread_func, NULL) != 0) { printf("create error\n"); } if (pthread_cancel(tid) != 0) { // cancel thread printf("cancel error\n"); } pthread_join(tid, (void **)retval); printf("main thread exit\n"); return 0; }
要获得“取消点”,您需要使用pthread_setcancelstate()
在线程函数启动时禁用取消,然后在需要时启用它。 当一个新线程产生时,它的取消状态为“enabled”,意味着它可以随时被取消。
也许更重要的是,你可能根本不应该使用pthread_cancel()
。 有关更多信息,请参阅此处: 使用pthread_cancel取消线程:良好实践或错误
取消线程永远不会意味着它会立即取消正在运行的任何东西。 它只是发布一个请求到该线程。 pthread_cancel只取消一个取消点的线程。 取消点的列表在pthreads
的手册页中定义。 在上面的线程中,你没有任何代码是一个取消点。 所以线程将永远完成,永远不会被取消。 您可以增加循环,或者在线程的最后一行放置一个打印语句,您将看到它始终正在完成线程。
但是,如果更改下面的代码以添加usleep
(它是手册页中定义的取消点之一),则可以看到线程在休眠之后终止。 即使您运行了任意次数,线程也只会在紧随usleep
之后的取消点处终止,而不会在任何其他点处终止。
#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> void *thread_func(void *arg) { int i; int j; int k; k = 1; /* add operation */ for (i=0; i<1000; ++i) { printf("Before - %d\n", i); usleep(1); printf("After - %d\n", i); for (j=0; j<10000;++j) { ++k; // maybe for(z=0; z<10000; ++z) added would // be better } printf("Never - %d\n", i); } printf("Normal Exit of thread\n"); return (void *)10; } int main(void) { char *retval; pthread_t tid; if (pthread_create(&tid, NULL, thread_func, NULL) != 0) { printf("create error\n"); } usleep(1000); if (pthread_cancel(tid) != 0) { // cancel thread printf("cancel error\n"); } pthread_join(tid, (void **)retval); printf("main thread exit\n"); return 0; }