【发布时间】:2011-05-11 22:09:03
【问题描述】:
我一直在研究 glibc/nptl 的取消点实现,并将其与 POSIX 进行比较,除非我弄错了,否则这是完全错误的。使用的基本模型是:
int oldtype = LIBC_ASYNC_CANCEL(); /* switch to asynchronous cancellation mode */
int result = INLINE_SYSCALL(...);
LIBC_CANCEL_RESET(oldtype);
根据 POSIX:
在函数调用期间暂停时对取消请求采取行动的副作用与在单线程程序中当函数调用被信号中断时可能看到的副作用相同并且给定的函数返回 [EINTR]。任何此类副作用都会在调用任何取消清理处理程序之前发生。
我对这篇文章的解读是,如果我调用open,我可以预期它要么在它无法打开文件之前被取消(连同我的整个线程),或 返回一个有效的文件描述符或 -1 和 errno 值,但永远不要创建一个新的文件描述符然后将其丢失到 void 中。另一方面,取消点的 glibc/nptl 实现似乎允许在系统调用返回之后但在 LIBC_CANCEL_RESET 发生之前发生取消请求的竞争条件。
我疯了,还是他们的实现真的这么糟糕?如果是这样,POSIX 是否允许这种破坏行为(这似乎会使取消完全无法使用,除非您手动推迟它),还是他们只是公然无视 POSIX?
如果这种行为实际上被破坏了,那么在没有这种竞争条件的情况下实现它的正确方法是什么?
【问题讨论】:
标签: c linux pthreads posix glibc