【问题标题】:How to implement a unmanaged thread-safe collection when I get this error: <mutex> is not supported when compiling with /clr当我收到此错误时如何实现非托管线程安全集合:使用 /clr 编译时不支持 <mutex>
【发布时间】:2013-04-04 21:21:00
【问题描述】:

我有一个 C++ 应用程序,它由非托管 C++、托管 C++ 和 c# 组成。在非托管部分,我尝试使用 std::mutex 创建线程安全集合。

但是,当我使用互斥体时,出现以下错误;

error C1189: #error : 在使用 /clr 或 /clr:pure 编译时不受支持。

知道为什么我不能使用互斥锁吗? 有人可以推荐一个替代品,以便我可以创建一个线程安全的非托管集合吗?

【问题讨论】:

标签: c++ multithreading thread-safety c++-cli mutex


【解决方案1】:

不支持,因为 std::mutex 实现使用 GetCurrentThreadId()。这是一个 不应该在托管代码中使用的 winapi 函数,因为它可能在不使用线程来实现线程的自定义 CLR 主机上运行。

这是一个很好的问题,它表明你正在构建错误的代码。您的本机 C++ 正在使用 /clr 进行编译。效果非常好,所有符合 C++03 的代码都可以编译为 MSIL 并在运行时即时编译,就像托管代码一样。您不希望这种情况发生,您的本机 C++ 代码应该编译为机器代码并获得编译时代码优化器的喜爱。

在您的项目中关闭此源代码文件以及可能的其他文件的 /clr 选项。右键单击 + 属性,常规。如果mutex 出现在你必须在C++/CLI 源文件中#include 的.h 文件中,那么你有一个更大的问题,使用接口或pimpl 来隐藏实现细节。

【讨论】:

  • “关闭此源代码文件的/clr选项...使用#pragma managed来回切换” - 原谅我的无知...你能提供一个简单的例子吗?
  • #pragma managed(push, off) .. 本机代码 .. #pragma managed(pop) 见msdn.microsoft.com/en-us/library/0adb9zxe.aspx
  • /clr 选项是否影响编译成静态库并最终链接到托管库的本机代码?也就是说,我编译了一个没有/clr的静态库。如果我编译将静态库与/clr 链接的库,它是否也会影响静态库?
  • 是和不是。没有/clr 编译的实际目标文件将被编译为真正的本地文件,但目标文件公开的任何公共符号(即几乎所有未在 cpp 中声明为 static 的东西)都将自动为它们声明托管符号 thunk .这只是一个符号名称,因此大多数情况下您并不关心,但这确实意味着本机类型和方法的名称将在托管反编译中可见。通常,这种尽可能多地编译到带有薄 /clr 包装器的静态非/clr 库的方法是最好的方法。
  • pimpl 解决方案安全吗?你不是在愚弄编译器吗?例如,C++/CLI 代码包含一个包含 pimpl 的标头,并且 impl 使用互斥锁,当 C++/CLI 代码调用一个反过来锁定互斥锁的函数时,不是从托管代码调用的 GetCurrentThreadId 可能不使用线程?
猜你喜欢
  • 2018-11-22
  • 2017-08-11
  • 1970-01-01
  • 2011-09-02
  • 2014-12-08
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
相关资源
最近更新 更多