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

Multi-threaded managed application that calls native code

本文关键字:应用程序 多线程 本机代码 调用      更新时间:2023-10-16

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

几个问题:

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

  2. 我怎么能确保GC不释放指针到托管缓冲区,而本机库正在操纵它?

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

修复托管内存:

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