【问题标题】:Blocking functions and EINTR阻塞函数和 EINTR
【发布时间】:2012-10-29 19:47:03
【问题描述】:

许多 POSIX 阻塞函数在收到信号时返回 EINTR。这个想法是信号处理程序首先设置一个标志(在 SIGINT 的情况下说“停止”标志),然后阻塞函数解除阻塞返回 EINTR 并且应用程序看到该标志并执行有序关闭(或其他)。

但是,对于一些阻塞函数,例如 pthread_mutex_lock 和 pthread_cond_wait,没有 EINTR 错误。

这背后的想法是什么?使用这些函数的应用程序应该如何处理信号(特别是 Ctrl+C)?

【问题讨论】:

  • 好吧,想象一下pthread_mutex_lock() 是可中断的。如果它被中断,下面的代码应该做出什么假设?互斥锁是锁定的还是解锁的?或者可能是介于两者之间......周围的代码如何重新启动操作? EINTR 并不总是打算请求关闭,很多时候重试是适当的操作......
  • pthread_cond_wait() 在这里更有趣,因为它旨在等待无限的时间。

标签: signals blocking eintr


【解决方案1】:

没有答案。我的假设是 pthread_cond_wait() 和 SIGINT 不能结合起来执行干净的关闭。使用 sem_wait() 或类似方法代替 pthread_cond_wait()。

【讨论】:

    【解决方案2】:

    一般来说,只有系统调用(低级操作系统调用)返回 EINTR。更高级别的标准库调用没有。例如,readwrite 可能返回 EINTR,但 printfgets 不会。

    通常,接收EINTR 时正确的做法是重做调用——这就是信号处理程序上存在 SA_RESTART 标志的原因。如果你想处理 Ctrl-C,你只需要不要忽略这个信号。退出的默认操作可能是您想要的,或者您可以编写自己的信号处理程序来执行其他操作。

    【讨论】:

    • 好吧,你可以写一个信号处理程序,但是然后呢?主线程仍然在 pthread_cond_wait() 中被阻塞,并且无法检查您碰巧在处理程序中设置的任何标志。是否打算在处理程序中调用 pthread_cond_signal()?
    • 在 Linux 上,man signal(7) 没有在信号安全函数中列出 pthread_cond_signal。有没有其他方法可以解除对主线程的阻塞?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 2020-11-07
    相关资源
    最近更新 更多