代码之家  ›  专栏  ›  技术社区  ›  R.. GitHub STOP HELPING ICE

POSIX取消点应该如何工作?

  •  9
  • R.. GitHub STOP HELPING ICE  · 技术社区  · 14 年前

    我一直在研究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?

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

    1 回复  |  直到 14 年前
        1
  •  4
  •   cmeerw    14 年前

    标准的下一段是否说明了这一点:

    但是,如果线程在 取消点和事件 它的等待发生在 取消请求已生效,它 未指定是否 取消请求根据或执行 是否取消请求 仍处于挂起状态,线程继续 正常执行。

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