两个线程交互会减慢彼此的速度吗?
这是一个非常概念性的问题。
假设我有 2 个独立的线程。线程 A 不断获取时间并将其存储为变量,线程 B 不断从线程 B 的变量获取时间并用它执行某些操作。
当线程B访问线程A中的变量时,线程A是否停止运行直到操作完成?
扩展一下,如果你有 3 个线程,线程 A 获取当前时间并将其设置为线程 B 中的变量,然后线程 C 读取该变量。
如果在线程 C 读取变量时线程 A 正在分配变量,那么线程是否会停止运行,直到 A 完成为止?
感谢您的精彩解答,但现在我还有 1 个问题。如果它们会干扰,那么使多个线程在通信时不竞争的首选解决方案是什么。 (概念上)你会做什么来让这些线程可以共享变量的值,同时保持尽可能快的速度?
This is a very conceptual question.
Let's say I have 2 separate threads. Thread A continually gets the time and stores it as a variable, and thread B continually gets the time from thread B's variable and does something with it.
The moment thread B accesses the variable in thread A, does thread A stop running until the operation is finished?
To expand, what if you had 3 threads, Thread A to get the current time and set it as a variable in Thread B, And then thread C to read the variable.
If Thread A is in the middle of assigning the variable the moment thread C comes to read it, does thread stop running until A is finished?
Thanks for the great answers, but now I have 1 more question. If they would interfere, what is the preferred solution to make the multiple threads not compete when communicating. (Conceptually) what would you do to make it so these threads could share the value of the variable while remaining as fast as possible individually?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
内存和线程是两个完全不同的东西。即使是代表线程的类的一部分的变量也只是内存,就像任何线程都可以访问的任何其他内存一样。
然而,使情况变得复杂并实际上导致速度变慢的是处理器缓存:为了使在不同 CPU 上运行的两个线程访问同一块内存并“查看”彼此的更改,CPU 缓存必须同步,这可以如果这种情况发生很多,就会完全抵消这些缓存的(巨大)速度优势。
请注意,由于缓存的原因,线程 B 实际上可能会在任意长时间内看到该变量的过时值,除非两者都在同步块中访问该变量,或者该变量是使用关键字 volatile 声明的。
Memory and thrads are two entirely different things. Even a variable that is part of a class which represents a thread is just memory like any other that any thread can access.
However, what complicates this and does in fact cause a slowdown is processor caches: in order for two threads running on different CPUs to access the same piece of memory and "see" each other's changes, the CPU caches have to be synchronized, which can completely negate the (massive) speed advantages of these caches if it happens a lot.
Note that because of caches, thread B may actually see an outdated value of the variable for an arbitrarily long time unless both access the variable within a synchronized block, or the variable is declared with the keyword
volatile
.通常不会,除非您声明 getter 和 setter 同步。如果从一个线程调用 setter,而另一个线程想要访问 getter,则必须等待另一个线程首先结束其任务。
我希望我正确理解了这个问题。
No normally not unless you declare the getter and the setter synchronized. If i.e. the setter is being called from one thread and another thread wants to access the getter it has to wait for the other thread to end his task first.
I hope I understood the question right.
它不会使线程 B 减慢线程 A 的速度。
但是:
1. 线程 A 可能会减慢线程 B 的速度。根据系统架构(核心和缓存),线程 A 的每次写入都会从线程 B 的 CPU 中清除缓存行。 B 的下一次读取将会更加昂贵。
2. 如果使用锁来保护数据结构,则两个线程都必须获得它。那么,显然,线程 A 的速度会变慢。
3. 如果您不使用锁,并且您的数据类型不是原子的,则可能会读取损坏的数据。例如,如果时间从 0x0000ffff 变为 0x00010000,则可能会读取到 0x0001ffff。通常,按 4 个字节对齐的整数是原子的,因此如果您的时间是 time_t ,则可能没问题。但细节取决于平台。
It won't make thread B slow thread A down.
But:
1. Thread A may slow thread B down. Depending on the system architecture (cores and caches), every write by thread A will purge the cache line from thread B's CPU. B's next read will be more expensive.
2. If you use a lock to protect the data structure, both threads have to obtain it. Then, obviously, thread A will slow down.
3. If you don't use a lock, and your data type isn't atomic, you may read corrupt data. For example, if the time changes from 0x0000ffff to 0x00010000, you may read 0x0001ffff. Normally, an integer, which is aligned on 4 bytes, is atomic, so if your time is time_t you're probably OK. But the details are platform dependent.
这取决于操作系统和 CPU 数量,但基本上是的,当一个线程正在工作时,另一个线程会等待。线程 B 是否使用线程 A 使用的变量并不重要,因为它们共享相同的内存。
It depends on the OS and the number of CPU, but basically yes, when one thread is working, the other waits. It doesn't matter much if thread B uses a variable used by thread A, as they share the same memory.
是的,他们放慢了速度。
这是因为您的并发性会检查您在应用程序中编写的代码:由于您有锁、信号量、监视器或其他任何东西来调节对存储变量的访问,因此每个线程可能会等待获得读/写变量的独占访问权。
即使您没有并发检查,我也很确定内存不允许同时读取或读/写:因为这种情况可能会发生,您的线程将被迫减慢一点
Yes they slow down.
And that's because your concurrency checks you coded in the application: since you have a lock, semaphore, monitor, or whatever, to regulate the access to the stored variable, each thread will possibly wait to gain exclusive access to read/write the variable.
and even if you don't have concurrency checks i am pretty sure that memory doesn't allow simultaneous reads or read/write: since this situation might happen, your threads will be forced to slow down a little bit nevertheless