我现在正在维护一些代码,用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。
答案 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函数找出挂起操作的完成时间。