是否有必要为只读线程和只写线程创建互斥锁?

发布于 2024-09-01 01:09:36 字数 162 浏览 2 评论 0原文

有2个线程,一个只读取信号,另一个只设置信号

是否有必要为signal创建互斥锁以及原因?

更新

我关心的是如果两个线程同时读取/设置它是否会崩溃

There are 2 threads,one only reads the signal,the other only sets the signal.

Is it necessary to create a mutex for signal and the reason?

UPDATE

All I care is whether it'll crash if two threads read/set the same time

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

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

发布评论

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

评论(4

北凤男飞 2024-09-08 01:09:36

您可能希望为此使用原子变量,尽管互斥体也可以工作。

问题在于,无法保证数据在线程之间保持同步,但使用原子变量可确保一旦一个线程更新该变量,其他线程就会立即读取其更新值。

如果一个线程更新缓存中的变量,而第二个线程从内存中读取该变量,则可能会出现问题。如果缓存尚未刷新到内存,第二个线程将读取变量的过时值。原子变量确保变量的值在线程之间保持一致。

如果您不关心及时的变量更新,您也许可以使用单个 volatile 变量。

You will probably want to use atomic variables for this, though a mutex would work as well.

The problem is that there is no guarantee that data will stay in sync between threads, but using atomic variables ensures that as soon as one thread updates that variable, other threads immediately read its updated value.

A problem could occur if one thread updates the variable in cache, and a second thread reads the variable from memory. That second thread would read an out-of-date value for the variable, if the cache had not yet been flushed to memory. Atomic variables ensure that the value of the variable is consistent across threads.

If you are not concerned with timely variable updates, you may be able to get away with a single volatile variable.

你爱我像她 2024-09-08 01:09:36

这取决于。如果写入是原子的,那么您不需要互斥锁。如果写入不是原子的,那么您确实需要锁。

还有编译器在 CPU 缓存中缓存变量的问题,这可能会导致主内存中的副本在每次写入时无法更新。有些语言有方法告诉编译器不要像这样在 CPU 中缓存变量(Java 中的 volatile 关键字),或者告诉编译器将任何缓存的值与主内存同步(Java 中的 synchronized 关键字)。但是,互斥体通常不能解决这个问题。

It depends. If writes are atomic then you don't need a mutual exclusion lock. If writes are not atomic, then you do need a lock.

There is also the issue of compilers caching variables in the CPU cache which may cause the copy in main memory to not get updating on every write. Some languages have ways of telling the compiler to not cache a variable in the CPU like that (volatile keyword in Java), or to tell the compiler to sync any cached values with main memory (synchronized keyword in Java). But, mutex's in general don't solve this problem.

玩心态 2024-09-08 01:09:36

如果您需要的只是线程之间的同步(一个线程必须先完成某件事,然后另一个线程才能开始其他事情),则不需要互斥。

仅当线程共享某些资源时才需要互斥,如果它们大致同时运行临界区,则该资源可能会被损坏。想象一下两个人共享一个银行帐户并且同时在两个不同的 ATM 机上。

根据您的语言/线程库,您可以使用与互斥相同的同步机制 - 信号量或监视器。因此,如果您使用 Pthreads,这里有人可以发布一个同步示例和另一个互斥示例。如果是java的话,还有另外一个例子。也许您可以告诉我们您正在使用什么语言/库。

If all you need is synchronization between threads (one thread must complete something before the other can begin something else) then mutual exclusion should not be necessary.

Mutual exclusion is only necessary when threads are sharing some resource where the resource could be corrupted if they both run through the critical section at roughly the same time. Think of two people sharing a bank account and are at two different ATM's at the same time.

Depending on your language/threading library you may use the same mechanism for synchronization as you do for mutual exclusion- either a semaphore or a monitor. So, if you are using Pthreads someone here could post an example of synchronization and another for mutual exclusion. If its java, there would be another example. Perhaps you can tell us what language/library you're using.

冬天的雪花 2024-09-08 01:09:36

如果,正如您在编辑中所说,您只想确保不会崩溃,那么您不需要做太多事情(至少作为规则)。如果线程之间发生冲突,最糟糕的情况是数据将被损坏 - 例如,读取器可能会得到一个已部分更新的值,并且不直接对应于写入线程曾经写入的任何值。经典的例子是你添加了一些东西的多字节数字,并且有一个进位,(例如)旧值是 0x3f ffff,它正在递增。读取线程可能会看到 0x3f 0000,其中低 16 位已递增,但向高 16 位进位尚未发生。

在现代机器上,这么小的数据项的增量通常是原子的,但会有一些大小(和对齐)不是原子的——通常如果变量的一部分位于一个缓存行中,部分位于另一个缓存行中,它将不再是原子的。确切的大小和对齐方式有所不同,但基本思想保持不变——这主要只是数字有足够的位数来实现的问题。

当然,如果您不小心,类似的事情可能导致您的代码死锁或按顺序发生某种情况 - 如果不知道您计划如何使用数据。

If, as you've said in your edit, you only want to assure against a crash, then you don't need to do much of anything (at least as a rule). If you get a collision between threads, about the worst that will happen is that the data will be corrupted -- e.g., the reader might get a value that's been partially updated, and doesn't correspond directly to any value the writing thread ever wrote. The classic example would be a multi-byte number that you added something to, and there was a carry, (for example) the old value was 0x3f ffff, which was being incremented. It's possible the reading thread could see 0x3f 0000, where the lower 16 bits have been incremented, but the carry to the upper 16 bits hasn't happened (yet).

On a modern machine, an increment on that small of a data item will normally be atomic, but there will be some size (and alignment) where it's not -- typically if part of the variable is in one cache line, and part in another, it'll no longer be atomic. The exact size and alignment for that varies somewhat, but the basic idea remains the same -- it's mostly just a matter of the number having enough digits for it to happen.

Of course, if you're not careful, something like that could cause your code to deadlock or something on that order -- it's impossible to guess what might happen without knowing anything about how you plan to use the data.

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