这里需要读写锁吗

发布于 2024-11-24 02:19:52 字数 536 浏览 0 评论 0原文

我已经编写了多线程代码。我不确定我是否需要读写锁机制。您能否仔细查看用例并告诉我是否必须使用读写锁,或者只需使用普通的互斥锁即可。

使用案例: 1)具有两个变量的类。每个线程在执行操作之前都会访问它们。 2) 当出现问题时,这些变量会更新以反映错误场景。 因此读取这些变量的线程可以做出不同的决定(包括中止)

这里,在第二点中,我需要更新数据。在第一点中,每个线程都会使用数据。所以,我的问题是我是否必须在更新数据时使用写锁,在读取数据时使用读锁。 (注意:两个变量都在内存中。只是一个布尔标志和字符串)

我很困惑,因为我的两个变量都在内存中。操作系统在完整性方面也很关心。我的意思是,当某个线程在互斥体中写入数据时,我可以忍受 1 或 2 个线程缺少更新值。

请告诉我是对还是错?另请告诉我是否必须使用读写锁或仅使用普通互斥锁即可。

更新:很抱歉,我没有提供平台和编译器名称。我使用 RHEL 5.0 并使用 gcc 4.6。我的平台是x86_64。但我不希望我的代码是特定于操作系统的,因为我们很快就会将代码移植到 Solaris 10。

I have writing a multi threaded code. I am not sure, whether I would need a read and write lock mechanism. Could you please go through the usecase and tell me do I have to use read-write lock or just normal mutex will do.

Use case:
1) Class having two variables. These are accessed by every thread before doing operation.
2) When something goes wrong, these variables are updated to reflect the error scenarios.
Thus threads reading these variables can take different decisions (including abort)

Here, in second point, I need to update the data. And in first point, every thread will use the data. So, my question is do I have to use write lock while updating data and read lock while reading the data. (Note: Both variables are in memory. Just a boolean flag & string)

I am confused because as my both vars are in memory. So does OS take care when integrity. I mean I can live with 1 or 2 threads missing the updated value when some thread is writing the data in mutex.

Please tell if I am right or wrong? Also please tell If I have to use read-write lock or just normal mutex would do.

Update: I am sorry that I did not give platform and compiler name. I am on RHEL 5.0 and using gcc 4.6. My platform is x86_64. But I don not want my code to be OS specific because we are going to port the code shortly to Solaris 10.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甲如呢乙后呢 2024-12-01 02:19:52

首先,忽略那些谈论易失性的其他回答者。 易失性是对于多线程编程来说几乎毫无用处,并且它所给出的任何错误的安全感都是错误的。

现在,您是否需要锁取决于您对这些变量执行的操作。您至少需要一个内存屏障(锁意味着一个)。

让我们举个例子:

  • 一个标志是错误标志。如果为零,则继续,否则中止。
  • 另一个标志是诊断代码标志。它给出了错误的确切原因。

在这种情况下,一种选择是执行以下操作:

  • 在没有锁的情况下读取错误标志,但在读取后使用读内存屏障。
  • 发生错误时,获取锁定,设置诊断代码和错误标志,然后释放锁定。如果诊断代码已设置,请立即解锁。

需要内存屏障,否则编译器(或 CPU!)可能会选择为每次读取缓存相同的结果。

当然,如果两个变量的语义不同,答案可能会有所不同。你需要更具体。

请注意,指定锁和内存屏障的确切机制取决于编译器。 C++0x 提供了可移植机制,但很少有编译器完全实现 C++0x 标准。请指定您的编译器和操作系统以获得更详细的答案。

至于你的输出数据,你几乎肯定需要一个锁。不过,请尽量避免过于频繁地获取这些锁,因为过多的锁争用会降低您的性能。

First off, ignore those other answerers talking about volatile. Volatile is almost useless for multithreaded programming, and any false sense of safety given by it is just that - false.

Now, whether you need a lock depends on what you're doing with these variables. You will need a memory barrier at least (locks imply one).

So let's give an example:

  • One flag is an error flag. If zero, you continue, otherwise, you abort.
  • Another flag is a diagnostic code flag. It gives the precise reason for the error.

In this case, one option would be to do the following:

  • Read the error flag without a lock, but with read memory barriers after the read.
  • When an error occurs, take a lock, set the diagnostic code and error flags, then release the lock. If the diagnostic code is already set, release the lock immediately.

The memory barriers are needed, as otherwise the compiler (or CPU!) may choose to cache the same result for every read.

Of course, if the semantics of your two variables are different, the answer may vary. You'll need to be more specific.

Note that the exact mechanism for specifying locks and memory barriers depends on the compiler. C++0x provides a portable mechanism, but few compilers fully implement the C++0x standard yet. Please specify your compiler and OS for a more detailed answer.

As for your output data, you will almost certainly need a lock there. Try to avoid taking these locks too often though, as too much lock contention will kill your performance.

溇涏 2024-12-01 02:19:52

如果它们是原子变量(C1x stdatomic.h 或 C++0x atomic),那么您不需要读/写锁。对于早期的 C/C++ 标准,根本没有使用多线程的可移植方法,因此您需要研究您正在使用的实现是如何工作的。在大多数实现中,可以使用单个机器指令访问的数据类型是原子的。

请注意,仅仅拥有一个原子变量是不够的——您可能还需要将其声明为易失性,以保证编译器不会执行导致您错过其他线程更新的操作。

If they are atomic variables (C1x stdatomic.h or C++0x atomic), then you don't need read/write locks. With earlier C/C++ standards, there's no portable way of using multiple threads at all, so you need to look into how the implementation you are using does things. In most implementations, data types that can be accessed with a single machine instruction are atomic.

Note that just having an atomic variable is not enough -- you probably also need to declare it as volatile to guarantee that the compiler does not do things that will cause you to miss updates from other threads.

心房的律动 2024-12-01 02:19:52

因此读取这些变量的线程可以做出不同的决定(包括中止)

因此每个线程需要确保它读取更新的数据。此外,由于变量是共享的,因此您还需要注意竞争条件。

简而言之 - 在读取和写入这些共享变量时,您需要使用读/写锁。

看看是否可以使用易失性变量 - 这应该可以避免您在读取值时使用锁(但是写入仍应使用锁)。这仅适用,因为您说过 -

我的意思是,当某个线程在互斥体中写入数据时,我可以忍受 1 或 2 个线程缺少更新值

Thus threads reading these variables can take different decisions (including abort)

So each thread need to ensure that it reads the updated data. Also since the variables are shared, you need to take care about the race condition as well.

So in short - you need to use read/write locks when reading and writing to these shared variables.

See if you can use volatile variables - that should save you from using locks when you read the values (however write should still be with locks). This is applicable only because you said that -

I mean I can live with 1 or 2 threads missing the updated value when some thread is writing the data in mutex

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文