上下文切换将如何导致竞争条件
我想知道在上下文切换期间竞争条件将如何发生,以及这种情况发生在哪里以及如何发生。
我知道访问共享资源时可能会出现竞争条件,我只需要更好地理解它。有人可以帮助我掌握这一点吗?
I want to know how race condition will happen during context switching, and where and how this happens.
I know about race condition can occur when accessing shared resource, I just need to understand it better. Can someone help me grasp this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个经典示例:
假设第一个线程开始运行,调用 update(),但在第二条和第三条指令之间被中断(通过信号、上下文切换等)。在此阶段
global_int==0
和register==1
:尚未保存结果。现在假设第二个线程运行
update()
并完成,因此global_int==1
。第一个线程恢复并将register
(即 1)保存到global_int
,不产生任何变化。在这种情况下,
global_int==1
在两次调用update()
完成后。任何假设update()
更新global_int
的行为现在都将被破坏。一般来说,通过查看代码非常很难检测到这个问题,您必须分析数据并对自己说“global_int 正在被不同的线程访问,我最好用互斥锁来保护它”。如果您试图变得聪明并担心线程如何访问它以避免锁的开销,那么您可能会出错,除非是在微不足道的情况下。
Here's a classic example:
Say the first thread starts running, calls
update()
, but gets interrupted (by a signal, context switch, whatever) in-between the second and third instructions. At this stageglobal_int==0
andregister==1
: it hasn't saved the result yet.Now suppose a second thread runs
update()
and completes, soglobal_int==1
. The first thread resumes and savesregister
(which is 1) toglobal_int
, yielding no change.In this situation,
global_int==1
after two calls toupdate()
have completed. Anything which assumes thatupdate()
updatesglobal_int
will now be broken.In general it is very hard to detect this problem by looking at code, you have to analyse the data and say to yourself "
global_int
is being accessed by different threads, I'd better guard it with a mutex". If you try to get clever and worry about how the threads will access it so as to avoid the expense of a lock, you will probably get it wrong except in trivial cases.竞争条件是并发执行代码访问共享资源而没有适当的机制来确保该共享资源的一致性的结果。
如果线程调度程序的实现中存在错误,导致用于执行上下文切换的代码访问共享资源而不提供适当的一致性保证,则在上下文切换期间可能会出现竞争条件。实现上下文切换的代码不会使其无法包含竞争条件。
Race conditions are a consequence of concurrent execution code which accesses a shared resource without proper mechanisms to ensure the consistency of that shared resource.
A race condition could occur during context switching if there is a bug in the implementation of the thread scheduler that causes the code used to perform the context switch to access a shared resource without providing proper consistency guarantees. There is nothing about the code that implements context-switching that makes it unable to contain race conditions.
假设您在一台带有调度程序的单处理器计算机上,该调度程序基本上对可用处理器资源执行时间切片(即,我们在一个非常简单的系统上)。然后假设您有代码的关键部分,但您没有使用互斥锁或其他同步原语来保护该关键部分。
假设线程 A 位于临界区内。当
线程 A
的时间片结束时,调度程序会调度另一个线程 B
并停止线程 A
。线程B然后进入临界区(因为没有防护),并修改临界区中共享内存中的值。当线程 B
的时间片结束时,操作系统会再次调度线程 A
,并从其在临界区内停止的位置继续执行。现在唯一的问题是,thread A
正在使用的值并不是它因上下文切换而停止时的值……它们完全不同,因为它们是由修改的>线程B
。因此你有一个竞争条件。Suppose you were on a single-processor machine with a scheduler that is basically performing time-slicing of the available processor's resources (i.e., we're on a really simple system). Then suppose you have a critical section of code, but you did not guard that critical section with a mutex or other synchronization primitive.
Assume
thread A
is inside the critical section. When the time-slice forthread A
is up, the scheduler schedules anotherthread B
and stopsthread A
.Thread B
then enters the critical section (since there was no guard), and modifies the values in shared memory in the critical section. Whenthread B's
time-slice is up, the OS schedulesthread A
again which continues from the point it left off inside the critical section. The only problem now though is that the valuesthread A
is working with are not what they were when it was stopped for the context-switch ... they're completely different since they were modified bythread B
. Thus you have a race-condition.