POSIX取消点应该如何表现?

时间:2010-11-18 09:18:06

标签: c linux pthreads posix glibc

我一直在研究glibc / nptl的取消点的实现,并将它与POSIX进行比较,除非我弄错了,否则完全错误。使用的基本模型是:

int oldtype = LIBC_ASYNC_CANCEL(); /* switch to asynchronous cancellation mode */
int result = INLINE_SYSCALL(...);
LIBC_CANCEL_RESET(oldtype);

根据POSIX:

  

在函数调用期间暂停时对取消请求起作用的副作用与在函数调用中断函数调用时可能在单线程程序中看到的副作用相同并且给定的函数返回[EINTR]。任何此类副作用都会在调用任何取消清除处理程序之前发生。

我对这篇文章的解读是,如果我打电话给open,我可以预期 取消(以及我的整个帖子),然后才能打开文件,< em>或返回有效的文件描述符或-1和errno值,但永远不要创建新的文件描述符然后将其丢失到void中。另一方面,取消点的glibc / nptl实现似乎允许竞争条件,其中取消请求发生在系统调用返回之后但LIBC_CANCEL_RESET发生之前。

我疯了,还是他们的实施确实破了?如果是这样,POSIX是否允许这种破坏的行为(除非你手动推迟取消,这似乎会导致取消完全无法使用),或者他们只是公然忽略了POSIX?

如果这种行为实际上已被破坏,那么在没有这种竞争条件的情况下实施它的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

在标准的下一段中是否澄清了这一点:

  

但是,如果线程被暂停   取消点和事件   它等待的时间发生在   取消请求被采取行动,它   没有具体说明是否   取消请求被采取行动或   是否取消请求   仍然待定,线程恢复   正常执行。

这意味着这种竞争条件是完全合法的行为。

答案 1 :(得分:0)

这是acknowledged as a bug in glibc,并已在commit 6fe99352106cf8f244418f3708b3d5928e82e831中修复。

POSIX文本明确表示取消的情况下尚未发生副作用。 cmeerw的答案中引用的文字是:

  

它等待的事件发生在取消请求被执行之前,尚不确定取消请求是否被执行或者取消请求是否仍在等待状态,线程是否恢复正常执行。

如果已经发生了等待事件 (例如设备变得可用,文件描述符变得可读等),则

允许执行取消操作,但是如果事件已经被消耗 或具有其他副作用(例如,打开设备并分配文件描述符,使用管道或套接字中的数据等)。