跨线程同步属性的最佳方法

时间:2010-06-14 08:56:38

标签: c++ multithreading

我正在寻找关于在C ++中同步访问对象属性的最佳方法的一些建议。该应用程序具有一个具有10个属性的对象的内部缓存。这些对象将以集合形式请求,然后可以修改其属性并重新保存。它们可以在任何给定时间由2-4个线程访问,但访问不是很强烈,所以我的选择是:

  1. 使用关键部分锁定每个对象的属性访问器。这意味着许多关键部分 - 每个对象一个。

  2. 在请求时返回对象的副本,并具有更新功能,该功能会锁定单个关键部分以在适当时更新对象属性。

  3. 我认为选项2似乎效率最高但我只是想看看我是否错过了一个更合适的隐藏第三选项。

    谢谢, Ĵ

3 个答案:

答案 0 :(得分:1)

首先,我认为你担心错误的事情。您如何知道锁定或复制会导致代码中出现瓶颈?关键部分相当轻量级,不会产生太多开销,或者至少没有你想象的那么多。只需使用最轻量级的锁定原语。如果您预计系统将在多处理器硬件上运行,您甚至可以使用自旋锁。

其次,在性能提升之前,要担心并发模型的简单性(提示:更简单的模型更容易理解,更好地进行优化)。因此,如果您能负担得起,请复制对象,这将减轻处理TOCTOU竞争条件的痛苦,以防您在依赖于许多先前值的对象集上进行复杂的转换。

答案 1 :(得分:0)

您不需要关键部分,您需要互斥锁。

对每个对象使用一个互斥锁是完全合理的。在读取或写入任何属性之前锁定互斥锁,然后在完成后快速解锁。

当没有争用时,互斥锁的开销非常低。当有很多争用时,它们肯定会减慢你的程序。

答案 2 :(得分:0)

根据从对象读取属性所花费的时间(我猜它应该相当简单,比如读取int或std :: string),可以使用spin-locks作为#3。它们是同步线程的最快方法。也许选项#4,仅对整数有效,根本不进行锁定,仅使用atomic operations。也许,效率最高的解决方案是使用原子用于所有整数,每个属性的自旋锁用于简单类型(POD和简单对象,如std :: string)和每个对象互斥锁/ CS用于更复杂的任何东西。

只有分析器才能告诉您哪个是最佳选择。