我正在使用g ++版本4.4.3(Ubuntu 4.4.3-4ubuntu5
)和libpthread v.2-11-1。以下代码只是创建一个运行Foo()
的线程,并立即取消它:
void* Foo(void*){
printf("Foo\n");
/* wait 1 second, e.g. using nanosleep() */
return NULL;
}
int main(){
pthread_t thread;
int res_create, res_cancel;
printf("creating thread\n);
res_create = pthread_create(&thread, NULL, &Foo, NULL);
res_cancel = pthread_cancel(thread);
printf("cancelled thread\n);
printf("create: %d, cancel: %d\n", res_create, res_cancel);
return 0;
}
我得到的输出是:
creating thread
Foo
Foo
cancelled thread
create: 0, cancel: 0
为什么第二个Foo
输出?我是否在pthread_cancel
之后立即致电pthread_create
来滥用pthread API?如果是这样,我怎么知道什么时候触摸线程是安全的?如果我在两者之间粘贴一个printf(),我就没有这个问题了。
答案 0 :(得分:0)
我无法在稍微更新的Ubuntu上重现这一点。有时我得到一个Foo
,有时没有。我必须修改一些东西才能让你的代码编译(缺少标题,缺少对注释暗示的一些睡眠函数的调用以及未关闭的字符串文字),这表明你没有粘贴重现问题的实际代码。
如果问题确实存在,则可能表明glibc的IO库中存在一些线程取消问题。它看起来很像两个线程在相同的缓冲区内容上执行flush(stdout)
。现在这应该永远不会发生,因为IO库是线程安全的。但是如果有一些取消方案如下:线程在stdout
上有互斥,并且刚刚完成了刷新,但还没有更新缓冲区以清除输出。然后在它可以执行此操作之前取消它,主线程再次刷新相同的数据。