我正在使用内存池将图像数据存储在光线跟踪器中,而我正在使用最近最少使用的算法来处理释放内存块的问题。当只有一个线程时,这可以正常工作。当我添加更多线程时,LRU代码会中断。我正在使用链接列表来存储已访问块的历史记录,这是打破的部分,因为在访问块时,我必须修改链接列表中的指针,这会导致线程之间发生冲突。这是我能想到实现内存池的唯一方法,所以我不确定如何让它工作。
这是我用来将访问过的块带到最近使用的列表前面的代码,其中发生了内存读取错误:
LinkedListNode<int> *curTextureIndex = lastUsedTexture;
LinkedListNode<int> *prevTextureIndex = NULL;
//Find the requested texture in the recently used list
while(curTextureIndex->data != textureBlockIndex)
{
prevTextureIndex = curTextureIndex;
curTextureIndex = curTextureIndex->next;
}
if(curTextureIndex != lastUsedTexture)
{
//Bring this block to the front of the accessed list
if(prevTextureIndex != NULL)
prevTextureIndex->next = curTextureIndex->next;
curTextureIndex->next = lastUsedTexture;
lastUsedTexture = curTextureIndex;
//Set the tail of the list if necessary
if(lastUsedTexture_tail == curTextureIndex && prevTextureIndex != NULL)
lastUsedTexture_tail = prevTextureIndex;
}
有没有一种很好的方法来实现它,以便它适用于多个线程?
答案 0 :(得分:2)
您可以尝试使用关键部分。请在此处查看维基页面:http://en.wikipedia.org/wiki/Critical_section
如果你正在使用ATL或MFC,它们有自己的类,它们包含你可能更容易使用的低级对象。
对于MFC:CCriticalSection。
对于ATL:CComAutoCriticalSection。
您可以将所有链接列表操作代码放在一个关键部分中,并且当另一个使用它时,您不会让一个线程践踏该列表。
另外,对于LRU缓存,我建议你使用一个双向链表和一个列表指针的哈希表(用key = textureBlockIndex)来快速获取条目,而不是走列表和比较,会让它变慢
快速完成将确保您在关键部分花费的时间非常少,这是一件好事。
请参阅:LRU cache design