我编写了多线程代码。我不确定,我是否需要一个读写锁机制。你能不能通过这个usecase告诉我我必须用读写锁还是普通的互斥锁就行了。
用例: 1)具有两个变量的类。在执行操作之前,每个线程都会访问这些线程。2)当发生错误时,更新这些变量以反映错误场景。因此,读取这些变量的线程可以采取不同的决定(包括中止)。
在这里,在第二点,我需要更新数据。在第一点,每个线程都将使用数据。所以,我的问题是,在更新数据时必须使用写锁,在读取数据时必须使用读锁。(注:这两个变量都在内存中。只是一个布尔标志&字符串)
我很困惑,因为我的两辆车都在记忆里。操作系统也是如此,在完整性方面也是如此。我的意思是,当某个线程用互斥锁写入数据时,我可以忍受1到2个线程缺少更新的值。
请告诉我是对还是错?另外,请告诉我是否必须使用读写锁,或者只是普通的互斥。
更新:我很抱歉没有给出平台和编译器的名称。我在RHEL5.0上,使用gcc 4.6。我的平台是x86_64。但我不希望我的代码是操作系统特定的,因为我们将很快将代码移植到Solaris 10。
发布于 2011-07-14 20:41:13
首先,忽略那些谈论不稳定因素的其他答案。对于多线程编程,易失性几乎是无用的。,以及它给出的任何虚假的安全感,都只是--假的。
现在,您是否需要锁取决于您如何处理这些变量。您至少需要一个内存屏障(锁意味着一个)。
让我们举个例子:
在这种情况下,一种选择是执行以下操作:
内存屏障是必需的,因为否则编译器(或CPU!)可以选择为每次读取缓存相同的结果。
当然,如果两个变量的语义不同,答案可能会有所不同。你需要说得更具体些。
注意,指定锁和内存屏障的确切机制取决于编译器。C++0x提供了一种可移植的机制,但是很少编译器能够完全实现C++0x标准。请指定编译器和操作系统以获得更详细的答案。
至于您的输出数据,您几乎肯定需要一个锁。但是,尽量避免频繁地使用这些锁,因为过多的锁争用会影响性能。
发布于 2011-07-14 19:02:56
如果它们是原子变量(C1x stdatomic.h或C++0x atomic),则不需要读/写锁。在早期的C/C++标准中,根本不存在使用多线程的便携方式,因此您需要了解您所使用的实现是如何实现的。在大多数实现中,可以用单个机器指令访问的数据类型是原子的。
请注意,仅仅有一个原子变量是不够的--您可能还需要将其声明为volatile,以确保编译器不会做导致您错过其他线程更新的事情。
发布于 2011-07-14 18:55:31
因此,读取这些变量的线程可以采取不同的决定(包括中止)。
因此,每个线程都需要确保读取更新的数据。另外,由于变量是共享的,所以您也需要注意竞争条件。
因此,简而言之,需要在读取和写入这些共享变量时使用读/写锁。
查看是否可以使用易失性变量--这将使您在读取值时避免使用锁(然而,写应该仍然使用锁)。这只因为你说-
我的意思是,当某个线程正在用互斥体写入数据时,我可以忍受1到2个线程缺少更新的值。
https://stackoverflow.com/questions/6698332
复制相似问题