我有一个大树结构,多个线程同时在其上工作。理想情况下,我想为每个单元格设置一个单独的互斥锁。
我查看了pthread_mutex_t
in的定义,bits/pthreadtypes.h
它相当短,所以在我的情况下内存使用应该不是问题。
pthread_mutex_t
但是,当只为 8 个线程使用许多(比如说几千个)不同的 s 时,是否有任何性能损失?
如果您非常频繁地锁定和解锁,可能会受到惩罚,因为获取和释放锁确实需要一些时间,并且如果锁被争用,可能需要相当长的时间。
在这样的结构中使用许多锁时,您必须非常具体地了解每个锁实际锁定的内容,并确保小心 AB-BA 死锁。例如,如果您在锁定操作期间更改树的结构,则需要以一致的顺序锁定所有将更改的节点,并确保处理后代的线程不会混淆。
如果您有大量的锁,分布在内存中,缓存问题可能会导致性能问题,具体取决于架构,因为锁定操作通常会使至少部分缓存无效。
您最好的选择可能是实现一个简单的锁定结构,然后对其进行分析,然后在必要时对其进行改进以提高性能。我不确定你对这棵树做了什么,但如果你希望阅读的内容比更新的多得多,那么一个好的起点可能是整个树的单个读写器锁。
“我们应该忘记小的效率,比如大约 97% 的时间:过早的优化是万恶之源。” ——唐纳德·克努斯
需要说明您的锁定/访问模式才能正确评估这一点。如果每个线程一次只持有一个或几个锁,并且任何两个或多个线程同时想要同一个锁的概率很低(随机访问模式或圆形轨道上不同位置的 8 个跑步者以大致相同的速度或其他更复杂的事情运行),那么您将主要避免最坏的情况,即线程必须睡眠才能获得锁(或者在某些情况下必须让操作系统参与来决定谁获胜),因为你有线程少,锁多。
如果每个线程在任何时候都可能需要数百或数千个锁,那么事情就会开始改变。
I won't touch deadlock avoidance because I don't know anything about the container that you are using, but you need to be aware of the need to avoid them.