2

我正在开发一个在主线程中执行一些连续模拟的多线程 VC++(windows)程序。此模拟使用在同一线程或加载器线程中创建的对象(两者都可能是这种情况)。删除也是如此。

我这样做是为了在动态加载和卸载非常大的对象(由许多其他对象组成)时主线程不会阻塞。这基本上奏效了。但是(例如)当卸载线程不断地删除一个又一个对象时,其他线程的 new 和 delete 调用需要永远。这似乎是由一些内螺纹保护引起的。

我的下一步是通过汇集那些较小的对象来减少新/删除调用的数量。所以我写了一个原始的内存管理器。管理器使用 malloc() 分配一个 320 MB 的缓冲区,并使用 64 字节块为我的程序的其他部分提供分配功能。现在我使用placement new 来创建较小的对象。管理器的分配/释放方法完全受互斥(锁定)保护。

现在发生的事情是它根本无法在多线程环境中正常工作。自定义托管对象的修改被忽略等等。我假设发生的情况是整个缓冲区被视为单个变量,因此不能有读/写数据竞争。是这样吗?

在创建/删除完全不同的对象时限制对一个对象的访问不是您可以想象的选择。那么在这样的情况下该怎么走呢?

4

2 回答 2

2

news 和s在delete内部同步到单个 Windows 堆对象。

我所知道的最好的解决方案是直接使用HeapCreate HeapAllocHeapFree,为每个分配器线程创建一个 Heap 对象,并且每次都指定 HEAP_NO_SERIALIZE。

您必须确保分配的线程是释放的线程,即您必须将内存“归还”给分配的辅助线程。

于 2013-02-19T12:39:46.193 回答
0

是这样吗?

不,我不这么认为。所有的内存只是一个连续的地址空间。CPU 不知道变量,它只操作页面、缓存行和字节。

可能的原因:内存管理器中的错误。也许它分配的对象相互重叠,或者你的线程同步失败(顺便说一句,你绝对应该用关键部分替换你的互斥锁,请参阅 CComAutoCriticalSection 和 CComCritSecLock ATL 类以获得方便的 whappers - 对于短操作,它们的工作速度要快一个数量级比互斥锁)。

可能的原因:对象中的错误。也许您的对象在其地址之后写入了一个额外的字节,但是堆对分配大小进行了四舍五入,因此当使用 new 运算符使用的 HeapAlloc win32 API 分配每个对象时,它可以正常工作。

可能的原因:内存对齐问题。尝试将您分配的对象的地址至少对齐到 8。

于 2013-02-19T12:12:14.373 回答