pthread_cancel返回EINPROGRESS

时间:2014-04-22 16:41:33

标签: c multithreading pthreads posix cancellation

我现在正在维护一些代码,用pthread_create()创建一个pthread。该线程在创建后不久也会调用pthread_detach(pthread_self());。此外,它使用pthread_cleanup_push()推送清理处理程序。该线程的唯一取消点是在线程主循环结束时调用pthread_testcancel()

我现在看到,在某个时刻pthread_cancel()会在此线程上被调用,并且(几乎)总是返回非零值。检查错误导致EINPROGRESS。这到底是什么意思?因为手册页说明了

  

成功时,pthread_cancel()返回0

然而,它也提到了,

  

取消将被延迟,直到线程接下来调用作为取消点的函数。

因此,如果非零和errno的返回值等于EINPROGRESS意味着取消请求已排队,但尚未作出反应,我希望始终如此。但如果返回值为0表示成功,则必须表示不同的内容。

EINPROGRESS在这种情况下的含义是什么?我如何确定线程被正确取消或已被终止?


我正在使用libpthread-2.13运行Debian 7.4作为libc6的一部分:在VM中使用amd64 2.13-38 + deb7u1。

2 个答案:

答案 0 :(得分:1)

  

我现在看到,在某个时刻pthread_cancel()会在此线程上被调用,并且(几乎)总是返回非零值。检查errno会导致EINPROGRESS。

pthread*系列函数未设置errno,而是将错误代码作为函数值返回。

因此,不要仅针对pthread_cancel()测试对0的调用结果,而是实际将您返回的值解释为您正常的"在errno中查找,这是E*错误值之一。

int result = pthread_cancel(<some-pthread>);
if (0 != result)
{
  fprintf(stderr, "pthread_cancel() failed with error #%d: '%s'\n", result, strerror(result)); /* Better use strerror_r() in a multithreaded enviroment. */
}

顺便说一句:检查您似乎使用的libc的来源并未显示pthread_cancel()返回EINPROGRESS的任何提示。

答案 1 :(得分:0)

由pthread_setcancelstate(3)确定的线程的可取消状态可以启用(新线程的默认值)或禁用。如果线程已禁用取消,则取消请求将保持排队,直到线程启用取消。如果线程已启用取消,则其可取消性类型确定何时取消。

-

由pthread_setcanceltype(3)确定的线程的取消类型可以是异步的或延迟的(新线程的默认值)。异步可取消性意味着可以随时取消线程(通常是立即取消,但系统不保证这一点)。延迟可取消性意味着取消将被延迟,直到线程下一次调用作为取消点的函数。

EINPROGRESS:

在选择了非阻塞模式的对象上启动无法立即完成的操作。一些必须始终阻止的函数(如连接)永远不会返回EAGAIN;相反,它们返回EINPROGRESS以指示操作已经开始并且将花费一些时间。在调用完成之前尝试操作对象将返回EALREADY。

...how can I make sure, that the thread got canceled correctly 
or was already terminated?

您可以使用select函数找出挂起操作的完成时间。