在紧密连续创建和取消线程时的奇怪行为

时间:2011-08-04 15:20:01

标签: pthreads

我正在使用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(),我就没有这个问题了。

1 个答案:

答案 0 :(得分:0)

我无法在稍微更新的Ubuntu上重现这一点。有时我得到一个Foo,有时没有。我必须修改一些东西才能让你的代码编译(缺少标题,缺少对注释暗示的一些睡眠函数的调用以及未关闭的字符串文字),这表明你没有粘贴重现问题的实际代码。

如果问题确实存在,则可能表明glibc的IO库中存在一些线程取消问题。它看起来很像两个线程在相同的缓冲区内容上执行flush(stdout)。现在这应该永远不会发生,因为IO库是线程安全的。但是如果有一些取消方案如下:线程在stdout上有互斥,并且刚刚完成了刷新,但还没有更新缓冲区以清除输出。然后在它可以执行此操作之前取消它,主线程再次刷新相同的数据。