CLI DLL的本机库中的互斥锁的解决方法

时间:2015-02-11 05:31:53

标签: multithreading c++-cli mutex

我正在为本机C ++库编写C ++ / CLI包装器。在其中一个返回给CLI包装器的类中,使用线程,特别是标题中的#include <mutex>来定义类级别的互斥锁。

问题是一旦头文件被带入CLI代码(启用了/ clr选项),我在使用/ clr或/clr:pure编译时​​遇到错误<mutex>

阅读这篇文章How to implement a unmanaged thread-safe collection when I get this error: <mutex> is not supported when compiling with /clr,有一篇博客文章提到了一些可能的解决方法。但是,解决方法假设您不需要任何导致冲突的头文件,并且所有头文件都可以在类函数中完成,实质上是从CLI应用程序中隐藏线程函数。

对于类级别的互斥锁,情况并非如此。它必须在标题中。

有没有办法让CLI应用程序与带有线程的本机库一起工作?

是的,我知道托管代码和非托管代码之间存在GetCurrentThreadID()问题,但正确的方法是什么?或者没有办法绕过它?

我不得不加入像ZMQ这样的东西,因为这是一个关键的部分,现在有三个数据副本(可能非常大)将是令人望而却步的。 (一个在托管端,一个在本机上,一个在ZMQ中通过消息缓冲区)。我知道ZMQ的零拷贝,但是没有尝试在托管和非托管c ++之间使用inproc来查看是否可以共享内存。如果可能的话,可能需要在整个应用程序中使用低级别的连续数据结构,否则会再次复制数据。

有没有像样的解决方案?

3 个答案:

答案 0 :(得分:1)

解决方案是使用#ifdef在CLI代码中有选择地隐藏.h文件中的互斥体声明,但仍在cpp本机代码中对其进行编译。

nativeClass.h文件:

#ifdef NATIVE_CODE
    #include <mutex>
#endif

class naticeClass {
public:
    void doSomething();
private:
#ifdef NATIVE_CODE
    mutex _mutex;
#endif

};

在nativeClass.cpp中:

#define NATIVE_CODE 
#include "nativeClass.h"

void nativeClass:doSomething()
{
    _mutex.lock();
    ...

}

答案 1 :(得分:0)

我之前为std :: thread研究了这个问题,我发现以下内容正在发挥作用。由于CLR不允许您在编译时包含std::thead,因此您可以尝试仅在链接时使用它。通常你可以解决这个问题,在你的标题中声明类,并将它们仅包含在你的cpp文件中。但是,可以转发在头文件中声明自己的类,但不能用于命名空间std中的类。根据C ++ 11标准,17.6.4.2.1:

  

如果添加声明或者C ++程序的行为是未定义的   命名空间std或命名空间std中的命名空间的定义   除非另有说明。

此问题的解决方法是创建一个继承自{strong>可以向前声明的std::thread的线程类。此类的头文件如下所示:

#pragma once
#include <thread>
#include <utility>
namespace Threading
{
    class Thread : std::thread
    {
    public:
        template<class _Fn, class... _Args> Thread(_Fn fn, _Args... args) : std::thread(fn, std::forward<_Args...>(args...))
        {

        }
    private:

    };
}

在您想要使用该主题的头文件中,您可以将其声明为:

#pragma once

// Forward declare the thread class 
namespace Threading { class Thread; }
class ExampleClass
{
    public:
        ExampleClass();
        void ThreadMethod();
    private:
        Threading::Thread * _thread;
};

在源文件中,您可以使用theading类,如:

#include "ExampleClass.h"
#include "Thread.h"

ExampleClass::ExampleClass() :
{
    _thread = new Threading::Thread(&ExampleClass::ThreadMethod, this);
}

void ExampleClass::ThreadMethod()
{
}

你应该可以为std :: mutex做同样的事情。希望它可以帮助任何人。

原帖:using clr and std::thread

答案 2 :(得分:0)

这就是我解决此问题的方法-通过创建自卷式Mutex。由于等待时间太长,我对解决方案并不感到高兴,但它似乎很好用。我只需要保护对std :: vector的多线程访问。

in .h file:
    std::atomic<int> vectorLock = 0;
in .cpp file:
    while (vectorLock.exchange(1) == 1) {}
         ... critical code goes here
    vectorLock = 0;