【问题标题】:Win32 Where is the console code running? Console hang when used from multiple threadsWin32 控制台代码在哪里运行?从多个线程使用时控制台挂起
【发布时间】:2012-10-18 01:40:13
【问题描述】:

我有一个使用两个线程的 C++ Win32 应用程序。 线程 A 使用AllocConsole() 创建一个控制台窗口。 线程 B 使用 WriteFile 打印到控制台句柄(来自 GetStdHandle)。

由于某种原因,当两个线程同时打印到控制台时,我的进程挂起。

如何解决此挂起问题?是什么原因造成的? 我想调试控制台的消息循环(它是一个窗口对吗?所以它应该有消息)但我不知道如何访问它?

【问题讨论】:

  • 有与该描述相符的代码吗?
  • 请您详细说明“...挂了。”。

标签: c++ c multithreading winapi console


【解决方案1】:

我怀疑问题在于并发调用WriteFile() 使用相同的设备句柄

每个线程都需要自己的设备句柄。只需在主线程中通过HANDLE = GetStdHandle(STD_OUTPUT_HANDLE) 拉动它,然后在两个线程中使用它来执行WriteFile(HANDLE, ...) 肯定行不通。

解决此问题的直接方法是通过使用CONOUT$ 调用CreateFile(),让每个线程都有自己的HANLDE 值。

在 OP 的情况下,只有线程 B 需要通过调用 CreateFile() 创建自己的句柄,线程 A 可以使用 GetStdHandle() 返回的值,因为它分配了控制台。

关于如何在“备注”部分中为“控制台”创建控制台see here 的设备句柄。

【讨论】:

    【解决方案2】:

    由于您没有提供任何代码,因此我将在这里进行有根据的猜测:

    据我所知,Win32 Console 类不是线程安全的(不像 System.Console 类在.NET 中是线程安全的)。

    这基本上意味着您应该进行一些同步以防止任何错误;我不知道那里的挂起是否是由这样的问题引起的。

    请向我们提供代码。

    编辑:
    请查看 Raymond Chen 的评论。

    【讨论】:

    • 控制台是线程安全的,但它是同步的。这意味着如果one thread is reading from the console, another thread cannot write.
    • 所以多次写入应该没问题?
    • 每次写入都等待前一次写入完成。
    • 如果使用相同的设备句柄,则需要同步。如果每个线程都使用自己的(正确创建的)句柄,则同步由操作系统完成。请看我的回答。
    • 谢谢。在我的情况下,必须共享句柄,因为它是一种在线程之间偶尔使用的全局实例化日志库,因此“挂起”是由于滥用了保护句柄的同步对象以及控制台是同步的事实。只是出于好奇,MSDN 中是否有任何关于控制台是同步的参考?
    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 2013-09-17
    相关资源
    最近更新 更多