如果 ANSI C++ 不支持多线程,非托管 C++ 应用程序如何实现多线程?

Posted

技术标签:

【中文标题】如果 ANSI C++ 不支持多线程,非托管 C++ 应用程序如何实现多线程?【英文标题】:If ANSI C++ doesn't support multithreading, how can unmanaged C++ apps be multithreaded? 【发布时间】:2009-05-11 00:19:11 【问题描述】:

我听说 C++ 不提供对多线程的本机支持。我假设多线程 C++ 应用程序依赖于多线程的托管代码;也就是说,例如,一个 Visual C++ 应用程序使用 MFC 或 .NET 或类似的东西来提供多线程功能。我进一步假设非托管应用程序无法使用部分或全部这些托管代码功能。但是我已经阅读了有关非托管多线程应用程序的信息。这怎么可能?我的哪个假设是错误的?

【问题讨论】:

【参考方案1】:

提供对多线程的支持完全取决于操作系统。在 Windows 上,必要的功能可通过 Win32 API 获得。诸如MFC 之类的框架提供了对低级线程函数的封装以简化操作,当然.NET/CLR 有自己的托管接口来访问 Win32 多线程功能。

this article 中提供了很好的解释(C++ 中的多线程)。

为什么 C++ 不包含内置 支持多线程?

C++ 不包含任何内置的 支持多线程 应用程序。相反,它依赖于 完全依赖于操作系统 提供此功能。鉴于两者 Java 和 C# 提供内置支持 对于多线程,很自然 问为什么不是这样 C++。答案是效率, 控制和应用范围 应用了 C++。让我们检查一下 每个。

通过不构建支持 多线程,C++ 不尝试 定义“一刀切” 解决方案。相反,C++ 允许您 直接使用多线程 由操作提供的功能 系统。这种方法意味着您的 程序可以是多线程的 最有效的手段支持 执行环境。因为很多 多任务环境提供丰富的 支持多线程,能够 获得这种支持对于 创造高性能, 多线程程序。

【讨论】:

虽然 MFC 确实包含线程功能,但它只不过是对本机 Win32 线程功能的薄包装。事实上,Windows 上的所有线程(甚至 .NET)只是原生 Win32 线程之上的一层。 @Greg:是的,这绝对正确。我应该澄清我的帖子。【参考方案2】:

C++ 中的多线程不需要托管代码。

与 C++ 不提供对显示图形或发出声音或从鼠标读取输入的本地支持非常相似,所使用的操作系统将提供 C++ API 来利用这些功能。

这不是 C++ 做不到的问题。它还没有被写入 C++ 标准。

【讨论】:

它也需要吗?我认为 C++ 最好不内置任何线程模型。 与图形、声音和鼠标输入的完美对比。 @Chris Huang-Leaver:在这种情况下,“需要”是一个很难定义的词,但是线程是即将到来的 C++ 标准。【参考方案3】:

您的一些假设并不完全正确。操作系统(我说的是win32,因为你提到了.NET)提供了对线程的支持。有很多好的线程库。它建立在 C++ 中的操作系统功能之上,使多线程“更容易”:) -- 例如pthreads。 Here is more at MSDN.

【讨论】:

【参考方案4】:

C++ 编程语言的 ISO 标准既没有定义也没有禁止多线程。如果需要,允许实现提供扩展。程序可以根据需要使用实现扩展,然后该程序将仅在提供这些扩展的系统上运行。

作为比较,C++ 编程语言的 ISO 标准既没有定义也没有禁止使用鼠标。允许程序使用实现扩展,然后它将仅在提供这些扩展的系统上运行。作为另一个比较,C++ 的 ISO 标准既没有定义也没有禁止 UTF-8,因此您的程序可以依赖于 Latin-1,然后您的程序将只能在提供 Latin-1 的系统上运行。

【讨论】:

【参考方案5】:

Native C++ 不提供“内置”多线程支持,仅仅是因为它并非有意或实际上不需要。 您的误解是这是一个错误,而实际上它是语言的优势。通过“无视”多线程,C++ 与您的代码将在其上编译和运行的操作系统提供的 MT 支持无缝集成,从而提供比它自己的“MT 包袱”更多的灵活性和效率。 您提到 MFC 和 .NET 作为示例 - 请注意,这些库/包装器只是基本 Win32 API 的一层。按预期使用 C++ 将为您提供可在任何操作系统上多线程运行的高效代码,只要您将逻辑与特定于操作系统的 MT API 调用(即线程创建等)分开,从而极大地促进操作系统之间的移植。

【讨论】:

如果它是语言的强项,为什么要为 C++0x 删除它?【参考方案6】:

与定义语言结构和 JVM 规范的 Java 不同,C++ 标准忽略了线程(C 也是如此)。就这些语言而言,任何与线程相关的内容都包括对操作系统功能的函数调用。为多线程编译的库只是对相同的调用有意义,但从语言的角度来看,它们是普通的旧代码。

【讨论】:

【参考方案7】:

我认为您误解了“托管”代码的定义。 “托管”代码是 Microsoft 特定的术语,意思是使用 .NET 框架的代码,因此受 .NET 各个方面的约束。 “非托管”代码是指在其外部运行且不通过 .NET 层运行的代码。 MFC 代码是“非托管”的;它只是对无处不在的 Win32 API(甚至不是 Windows 上可用的最低级别 API)的一个非常糟糕的包装器。

.NET 库(包括多线程)在某种程度上几乎都是传统“非托管”应用程序使用的更基本系统 API 的接口。一般而言,“托管”代码没有可用的功能,无法通过足够的努力在“非托管”代码中复制,尽管反之亦然(如果您想了解更多信息,这称为抽象惩罚)。虽然在“托管”代码中执行此操作可能更容易,但这只是因为在某个地方,一些“非托管”代码或多或少地为你做这件事。在线程 API 的情况下,它又是操作系统内核的接口,它本身访问处理器的功能以允许进程同时在多个地方运行(如果使用多个内核;如果没有,那么它只是一个伪-并发)。

C++ 标准目前没有提供线程的定义(即将到来的 C++1x 标准提供)。有许多不同的线程库可用,包括 Win32 和 MFC 提供的、POSIX 系统上的 pthreads 库和 Boost.Thread,它将使用平台的本地线程库。

【讨论】:

【参考方案8】:

下一个 C++ 标准(名为 c++0x)将支持多线程。 将包括原子操作。

【讨论】:

以上是关于如果 ANSI C++ 不支持多线程,非托管 C++ 应用程序如何实现多线程?的主要内容,如果未能解决你的问题,请参考以下文章

通过 CLI 包装器在非托管 C++ 中使用 C#.NET Winform - 需要线程?

C#EXE w / Unmanaged C ++ Unicode DLL链接到非托管C ++ ANSI DLL崩溃

ANSI C 兼容或 C++ 跨平台 GUI 库?

是否可以在线程中对非托管函数执行C#回调?

在 C# 应用程序退出时清理非托管 C++ 线程

是否在CLR上运行非托管Visual C ++?