【问题标题】:Is there way to make a thread come out of an infinite semaphore wait when the process is killed?当进程被杀死时,有没有办法让线程从无限信号量等待中出来?
【发布时间】:2012-01-01 02:39:20
【问题描述】:

操作系统:Windows。 语言:C

我有一个线程通过 TCP 向服务器发送请求,并在信号量上无限等待响应。还有另一个线程读取套接字,将接收到的数据复制到一个公共缓冲区中,并脉冲信号量以退出等待。这一切都很好。但是在进程由于某种原因被终止的情况下,等待信号量的线程会一直等待,而其他线程会终止。

当进程被杀死时,为什么线程等待信号量没有结束?我在 Linux 论坛上读到 SEM_UNDO 在这种情况下会有所帮助。 Windows上有类似的东西吗?有什么解决办法吗?

【问题讨论】:

  • 您是如何创建线程 _beginthread 或 _beginthreadex 的?
  • 只需让其他进程创建信号量即可。因此,当杀死进程会破坏它时,您会得到 WAIT_ABANDONED。
  • @HansPassant - 一定有其他事情发生。 Windows 不关心进程终止时线程处于什么状态 - 进程中的所有线程都已停止。 MSDN 说:'如果一个线程正在等待一个内核对象,在等待完成之前它不会被终止。这可能会导致应用程序挂起。根据经验,在 W95 以来的每个 Windows 上,这都是不正确的 - 等待信号量的线程不会阻止应用程序自行关闭(ExitProcess)或被终止(TerminateProcess)。
  • @Martin - Exit/TerminateProcess 没有什么好处,线程在没有追索权的情况下被杀死。在任何 C 或 C++ 程序中都可见,它在 main() 函数返回时结束,与线程无关。
  • @HansPassant - 对,那么为什么 OP 有这个问题?为什么OP进程不会终止?

标签: c windows multithreading semaphore freeze


【解决方案1】:

Semaphores do not have owners。如果您等待信号量,那么您正在等待 任何人 发出信号。没有办法声明“发出信号量是这家伙的责任,如果他没有发出信号就终止了,那么我应该做点什么来恢复。”

如果您想要一个所有者可跟踪的同步对象,请使用互斥锁。或者,您可以让服务员也等待其他进程句柄,并在检测到其他进程已终止时执行恢复。

【讨论】:

  • 挂起的线程无法查明服务器是否处于活动状态。当进程被杀死时,Windows 应该已经结束了挂起的线程。我认为保持线程运行没有意义。
  • 如果任何人(不仅仅是被杀死的线程)发出信号量信号,线程就会唤醒。 Windows 无法预测未来并说“我预测没有人会发出这个信号量”,所以它会一直等待以防万一。如果您想要所有权语义,请使用互斥体。
【解决方案2】:

当进程终止时(如TerminateProcess),该进程中的所有线程也将终止。没有例外。这就是系统的工作方式。如果某个线程仍然处于活动状态,那么这自动意味着它的进程也处于活动状态。所以,你看到的和你想象的不一样。要验证该进程是否真的被“杀死”(或在 Windows 世界中终止),请使用任务管理器和进程选项卡。

【讨论】:

  • 是的。几十年来,我在 Windows 操作系统上部署了大量多线程应用程序。我使用基于生产者-消费者队列的消息传递设计——线程等待队列类中的信号量,通常具有无限超时。当我或我的客户点击“关闭”图标时,整个应用程序会立即关闭,无需明确发出信号、销毁或以其他方式摆弄任何信号量。
  • 我相信您的应用程序中有一个“关闭”事件处理程序可以优雅地关闭应用程序。但在我的情况下,该进程正在通过 Windows 任务管理器被杀死。所以没有优雅的关闭。
  • @Shashi,如果从“应用程序”选项卡和“进程”选项卡关闭应用程序,则存在差异。从应用程序选项卡关闭应用程序时,任务管理器首先尝试所有关闭应用程序的好方法。从进程选项卡任务管理器关闭应用程序时立即调用 TerminateProcess.
  • 是的。感谢大家的回复。
猜你喜欢
  • 1970-01-01
  • 2013-08-19
  • 2021-09-10
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
相关资源
最近更新 更多