【问题标题】:How do handlers for CtrlEvents work in a multithreaded environment?CtrlEvents 的处理程序如何在多线程环境中工作?
【发布时间】:2018-02-05 04:39:36
【问题描述】:

在 C 控制台应用程序中,如果我在主线程中使用 SetConsoleCtrlHandler 并且还有其他线程正在运行,那么当事件发生时,所有线程都会停止并在新线程中执行处理程序吗?或者有没有办法让一个线程只执行处理程序并在其他线程中忽略它,有点像 Unix 中的pthread_sigmask

在 StackOverflow 和互联网上都没有太多关于这个主题的信息,所以我希望这会变得有用。

【问题讨论】:

    标签: c multithreading winapi


    【解决方案1】:

    以上都不是。

    documentation for the handler routine中所述:

    当收到信号时,系统在进程中创建一个新线程来执行函数。

    如果您需要特定线程来响应控制台控制信号,则您有责任编写处理程序例程来联系该线程,使用最适合您的代码的任何线程间通信方法。

    确保处理程序例程是线程安全的也是您的责任,因为在处理信号时现有线程将继续正常运行。


    请注意,控制台控制信号与 POSIX 信号并不十分相似。一方面,它们通常只影响控制台应用程序(GUI 应用程序不会接收控制台控制信号),另一方面,它们并非设计或打算用作 IPC 机制。另外,当然,它们从不中断现有线程。

    Microsoft C 运行时确实按照标准的要求实现了 C 信号,但这些信号也不像 POSIX 信号;最值得注意的是,它们只是进程内的。作为一个特例,如果你配置一个 SIGINT 处理程序,它会被实现为一个控制台控制处理程序,但是这个功能is officially unsupported 我建议不要使用它。

    【讨论】:

    • 是的,我根本不想使用POSIX信号,我宁愿学习Windows的方式来解决这些问题。如果我希望线程优雅地终止,是否可以将窗口消息从处理程序发送到其他线程,然后从那里管理关闭过程?
    • @EärendilBaggins:发出线程终止信号的更好方法是使用手动重置Event Object,线程定期检查并在发出信号后终止。您可以等待线程终止调用WaitForMultipleObjects
    • IMO,最好只对自然有窗口消息循环的线程使用窗口消息,一般只有主线程。对于其他线程,这取决于它们在做什么,但是事件对象(正如 IInspectable 所建议的那样)通常是一个很好的通用选择。 APC 可以更优雅,但这取决于线程的主循环是什么样的,并且它们可能更难掌握。
    • 我肯定会检查事件对象,但这会导致另一个问题:那么在什么情况下使用窗口事件进行线程/进程间通信可能是明智的?
    • 你的意思是窗口消息?仅在 GUI 应用程序中,并且仅对主线程(已经有一个窗口消息循环)。这不是一成不变的规则,但最好坚持下去,直到你知道自己在做什么。
    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 2012-05-29
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多