更好地锁定共享资源,还是有一个线程来满足请求?
我有一个共享内存池,许多不同的线程可以从中请求分配。从中请求分配将在每个线程中发生很多次,但是线程数量可能很小,通常只有 1 个线程在运行。我不确定以下哪种方法可以更好地处理这个问题。
最终我可能需要同时实现两者,看看哪一个会产生更有利的结果...我还担心,此时考虑 #2 可能是过早的优化,因为我实际上还没有编写使用此共享资源的代码。但这个问题非常有趣,以至于它继续分散我对其他工作的注意力。
1)创建一个互斥锁,并让一个线程在获得分配之前尝试锁定它,然后解锁它。
2)让每个线程注册一个请求槽,当需要分配时,它将请求放入槽中,然后阻塞(while(result == NULL){ usleep()})等待请求槽有结果。单个线程不断迭代请求槽,进行分配并将它们分配给请求槽中的结果。
第 1 种解决方案是简单的,但如果时机正确,单个线程可能会占用锁。第二个更复杂,但确保从资源中拉取时线程之间的公平性。然而,它仍然会阻塞请求线程,并且如果有很多线程,迭代可能会消耗周期而不进行任何实际分配,直到找到要满足的请求为止。
注意:Linux 上的 C 使用 pthreads
I have a shared memory pool from which many different threads may request an allocation. Requesting an allocation from this will occur a LOT in every thread, however the amount of threads is likely to be small, often with only 1 thread running. I am not sure which of the following ways to handle this are better.
Ultimately I may need to implement both and see which produces more favorable results... I also fear that even thinking of #2 may be premature optimization at this point as I don't actually have the code that uses this shared resource written yet. But the problem is so darn interesting that it continues to distract me from the other work.
1) Create a mutex and have a thread attempt to lock it before obtaining the allocation, then unlocking it.
2) Have each thread register a request slot, when it needs an allocation it puts the request in the slot, then blocks(while (result == NULL) { usleep() }) waiting for the request slot to have a result. A single thread continuously iterates request slots making the allocations and assigning them to the result in the request slot.
Number 1 is the simple solution, but a single thread could potentially hog the lock if the timing is right. The second is more complex, but ensures fairness among threads when pulling from the resource. However it still blocks the requesting threads, and if there are many threads the iteration could burn cycles without doing any actual allocations until it finds a request to fulfill.
NOTE: C on Linux using pthreads
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案2是假的。这是一个丑陋的黑客行为,它不能确保内存同步。
我想说采用解决方案 1,但我对您一开始提到的“内存池”这一事实有点怀疑。您只是想分配内存,还是正在管理其他一些资源(例如某种特殊类型内存中的插槽、内存映射文件、视频内存中的纹理等)?
如果您只是分配内存,那么您担心过早优化是完全正确的。整个问题是过早的优化,系统
malloc
会比你的内存池做得更好,甚至更好。 (或者,如果您的代码将在少数几个具有病态损坏malloc
的系统之一(例如某些视频游戏控制台)上运行,则只需在仅在那些已知损坏的系统上添加替换.)如果您确实有需要管理的特殊资源,请从解决方案 1 开始,看看它是如何工作的。如果您遇到问题,您可能会发现可以使用条件变量来改进它,其中资源管理器会在可以分配插槽时通知您,但我真的怀疑这是必要的。
Solution 2 is bogus. It's an ugly hack and it does not ensure memory synchronization.
I would say go with solution 1, but I'm a little bit skeptical of the fact that you mentioned "memory pool" to begin with. Are you just trying to allocate memory, or is there some other resource you're managing (e.g. slots in some special kind of memory, memory-mapped file, textures in video memory, etc.)?
If you are just allocating memory, then you're completely right to be worried about premature optimization. The whole problem is premature optimization, and the system
malloc
will do as well as or better than your memory pool will do. (Or if your code will be running on one of the few systems with a pathologically brokenmalloc
like some video game consoles, just drop in a replacement only on those known-broken systems.)If you really do have a special resource you need to manage, start with solution 1 and see how it works. If you have problems, you might find you can improve it with a condition variable where the resource manager notifies you when a slot can be allocated, but I really doubt this will be necessary.