以下是pthread取消的代码示例:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *my_routine(void *arg) {
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", i);
}
return NULL;
}
int main(void) {
pthread_t thread;
if (pthread_create(&thread, NULL, my_routine, NULL)) {
fprintf(stderr, "Cannot create pthread\n");
return 1;
}
usleep(20);
pthread_cancel(thread);
pthread_join(thread, NULL);
//fflush(stdout);
sleep(1);
return 0;
}
我编译:
gcc -pthread -Wall threadtest.c -o threadtest
执行时,有时会在 sleep(1)
之后打印一个的附加数字。
有时这个数字是重复的:
0
1
2
3
4
4 // printed after sleep(1)
有时不会:
0
1
2
3
4
5 // printed after sleep(1)
如果我fflush(stdout)
之前sleep(1)
,则会立即打印其他号码。
取消线程时如何避免这种奇怪的printf
行为?
谢谢。
答案 0 :(得分:0)
您可以在执行printf()
时停用取消并添加明确的取消点:
int cancel_state = 0;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
printf("%d\n", i);
pthread_setcancelstate(cancel_state);
pthread_testcancel();
(为了便于阅读,遗漏了错误检查)
答案 1 :(得分:0)
使用pthread_cancel时,你应该更加小心线程处理程序。
pthread_cancel的手册解释了很多。
man pthread_cancel
检查手册页中提供的示例程序
当线程处理程序启动时,您必须在pthread_setcancelstate系统调用的帮助下进行PTHREAD_CANCEL_DISABLE,当处理程序满足取消点设置PTHREAD_CANCEL_ENABLE时。
在主要检查pthread_cancel成功与否是在PTHREAD_CANCELED宏的帮助下。
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *my_routine(void *arg) {
int i;
//pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
for (i = 0; i < 10; i++) {
sleep(1);
printf("%d\n", i);
}
//pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
sleep(60);
return NULL;
}
int main(void)
{
pthread_t thread;
if (pthread_create(&thread, NULL, my_routine, NULL)) {
fprintf(stderr, "Cannot create pthread\n");
return 1;
}
usleep(20);
pthread_cancel(thread);
pthread_join(thread, NULL);
//fflush(stdout);
sleep(1);
return 0;
}
最初编译并运行上面的程序,记下输出。它可能不会显示任何内容并终止程序,因为在线程创建的线程处理程序将等待1秒并休眠后,在此时父线程将取消线程并完成进程。
然后从上面的程序取消注释两个pthread_setcancelstate(),现在编译并运行该程序。它现在将显示为1到9.因为线程设置为PTHREAD_CANCEL_DISABLE所以父pthread_cancel不会取消并等待PTHREAD_CANCEL_ENABLE。当线程处理程序遇到PTHREAD_CANCEL_ENABLE时,父线程将取消该线程。
注意输出时。处理程序不会保持睡眠状态(60),因为在该父程序将取消该程序之前。