调用本机代码的多线程托管应用程序

时间:2015-05-20 10:34:48

标签: c# c++ multithreading

我有一个使用ASP WebApi的服务。每个http请求都转换为需要进行一些数据操作的线程(可能会更改数据)。 API层是用C#编写的,数据操作是用C ++编写的。 C#层调用本机库并提供指向某个托管缓冲区的指针。

几个问题:

  1. 如何确保没有比赛?在这种情况下,本地库中的std::mutex是否足够? (托管线程是否映射到本机线程?它们是否共享相同的std::mutex?)

  2. 如何在本机库操作时确保GC没有释放指向托管缓冲区的指针?

1 个答案:

答案 0 :(得分:1)

  1. 您需要共享缓冲区吗?如果只在一个线程上使用缓冲区,则可以省去很多麻烦。托管线程不会以1:1的形式映射到本机线程,但我不确定这是否会对您的方案产生任何影响。
  2. 您需要修复缓冲区,并在本机代码指向它的整个过程中保持固定 - 释放是您最不担心的,.NET内存一直在移动。这是使用fixed块完成的。
  3. 修复托管内存:

    byte[] theBuffer = new byte[256];
    fixed (byte* ptr = &theBuffer[0])
    {
       // The pointer is now fixed - the GC is prohibited from moving the memory
       TheNativeFunction(ptr);
    }
    // Unfixed again
    

    但是,请注意,禁止GC移动内存会导致相当多的麻烦 - 例如,它可以在高吞吐量服务器中完全阻止堆压缩。

    如果您不需要在托管环境中使用内存,则可以简单地为任务分配非托管内存,例如使用Marshal.AllocHGlobal