C++ 混合模式进程与托管到非托管IPC
我正在努力为我正在从事的一个当前项目提出设计候选方案。它的客户端接口基于WCF服务,公开公共方法和回调。请求一直被路由到执行计算、操作等的C++库(C++ 混合模式进程与托管到非托管IPC,c++,.net,garbage-collection,c++-cli,ipc,C++,.net,Garbage Collection,C++ Cli,Ipc,我正在努力为我正在从事的一个当前项目提出设计候选方案。它的客户端接口基于WCF服务,公开公共方法和回调。请求一直被路由到执行计算、操作等的C++库( 当前的方案是基于WCF服务通过独立的IPC来与单独的本地C++进程对话的。 为了使事情变得简单一点,这里有一个建议,可以混合模式(即,有一个单一的.NET进程,它在其中加载本地C++层,最有可能通过非常薄的C++/CLI层与它通信)。主要关注的是垃圾回收或其他.NET方面是否会阻碍进程的非托管C++部分的性能。 我开始查找安全点和GC助手方法的概念
当前的方案是基于WCF服务通过独立的IPC来与单独的本地C++进程对话的。 <>为了使事情变得简单一点,这里有一个建议,可以混合模式(即,有一个单一的.NET进程,它在其中加载本地C++层,最有可能通过非常薄的C++/CLI层与它通信)。主要关注的是垃圾回收或其他.NET方面是否会阻碍进程的非托管C++部分的性能。 我开始查找安全点和GC助手方法的概念(例如KeepAlive(),等等),但我找不到任何关于这个或基准的直接讨论。据我目前所知,其中一个安全点是,如果一个线程正在执行未更改的代码,在这种情况下,垃圾收集不会挂起任何线程(这是否正确?)来执行清理
我想我的主要问题是,当在同一进程中运行这两种类型的代码时,与使用单独的进程相比,本机端存在性能问题。如果有一个线程从未执行过任何托管代码,它将不会在.NET垃圾回收期间冻结 如果使用托管代码的线程当前正在本机代码中运行,则垃圾回收器不会冻结该线程,而是在下次到达托管代码时将该线程标记为停止。但是,如果您正在考虑一个长时间不返回的本机分派循环,您可能会发现您正在阻塞垃圾收集器(或者将东西固定住,导致GC和碎片速度变慢)。因此,我建议让线程在本机代码中执行重要任务时保持完全纯净
确保编译器不为某些标准C++代码默默地生成MSIL(从而使其作为托管代码执行)有点棘手。但最终,您可以通过仔细使用
#pragma managed(push,off)
来实现这一点。如果您有一个线程从未执行过任何托管代码,它将不会在.NET垃圾收集期间被冻结
如果使用托管代码的线程当前正在本机代码中运行,则垃圾回收器不会冻结该线程,而是在下次到达托管代码时将该线程标记为停止。但是,如果您正在考虑一个长时间不返回的本机分派循环,您可能会发现您正在阻塞垃圾收集器(或者将东西固定住,导致GC和碎片速度变慢)。因此,我建议让线程在本机代码中执行重要任务时保持完全纯净
确保编译器不为某些标准C++代码默默地生成MSIL(从而使其作为托管代码执行)有点棘手。但最终,您可以通过小心地使用pragma managed(push,off)来实现这一点。启动并运行混合模式应用程序非常容易,但要使其正常工作可能非常困难
我建议在选择这种设计之前仔细考虑——特别是如何分层应用程序以及非托管对象的预期寿命。从过去的经验中得出的一些想法:在本地范围内简单地使用C++对象,然后立即处理它们。 这听起来很明显,但值得说明的是,C++对象是非托管资源,它们被设计成非托管资源。通常,他们期望确定性的创造和破坏——通常广泛使用RAII。从托管程序进行控制可能会非常棘手。IDispose模式的存在就是为了解决这个问题。这对于寿命短的对象很有效,但对于寿命长的对象来说相当繁琐,很难正确处理。特别是,如果您开始使非托管对象成为托管类的成员,而不是只存在于函数范围内的对象,那么很快程序中的每个类都必须是IDisposable的,并且托管编程突然变得比ummanaged编程更难