多线程和布尔寄存器
Multiple threads and a Boolean register
我的问题很简单;两个不同的线程能否在完全相同的时刻将布尔值设置为真或假?如果不是,为什么不?
如果不是当两个线程同时到达代码时会发生什么,如果它们将布尔值设置为某个值,硬件是否会任意地让一个等待片刻?
或者,如果他们可以,那么最终值是如何确定的?
无论是或否,是否适用于所有类型的变量?
它依赖于实现。它依赖于体系结构。它依赖于处理器负载,依赖于进程调度,几乎依赖于除月相之外的所有事物(我不会把钱花在最后一个上)。
简短的回答是,从长远来看,其中一个线程会成功。在短期内,他们可能对布尔值的实际值有不一致的看法,并且这些观点会在完全不确定(并且可能不一致)的时间段后发生变化。
硬件不会让一个线程等待,因为硬件不会自动知道它们都在同时尝试写入同一内存位置。从长远来看,它可能会注意到这一点,但到那时再做任何巧妙的事情都为时已晚。使用布尔值的线程将是其处理器缓存恰好写回缓存行 second 的线程。毕竟,您的处理器内核并不是每个都直接连接到您的 RAM 芯片。他们必须通过你的内存控制器,而你只有其中之一。
至于是否对所有变量都成立.....嗯。如果变量符合内存字,绝对适用于所有现代计算机体系结构。如果它适合一个缓存行,那么可能。但也有可能,特别是对于较大的结构,一半变量将来自一个线程,另一半来自另一个线程。如果线程正在 更新 内存(例如,将其递增 1)而不是仅 写入 内存(将其设置为它们的线程 ID ,比方说),那么这两个线程成功完成他们计划完成的任务的可能性会进一步降低。
顺便说一句,解决这个错误机会雷区的方法是(按实用性和性能的顺序)(a) 使用同步原语,如互斥锁,(b) 使用原子操作,以及 (c) 一个了解正在发挥作用的线程内存模型。
完全相同的时刻?我怀疑你可能会挑剔到没有这样的东西,除非你指定惯性参考系等等......
如果你是单核,肯定不行。它必须按时间切片 运行 多个线程。
如果你在一个处理器中有多个内核,只有一个数据和地址总线,那么仍然没有。两个进程不可能同时写入内存。处理器必须以特定方式与内存通信,具体取决于内存类型等 - 但基本上你必须设置一个地址,然后执行读取或写入周期来传输数据 - 你不能两个进程这样做。内存管理硬件会让其中之一等待。
如果你有两个处理器,共享内存,那么...仍然没有,如果当时设计系统的人是正确的。
但是从编程的角度来看,它们可以足够接近以至于它们还不如同时进行;使用关键部分或互斥锁或其他任何东西,并使其中一个线程后退一点,而另一个线程则读取、修改、写入。
但是如果你有一个大于你机器的字长的变量(在这个时代可能意味着 > 64 位)或者一个数组变量或类似的东西,那么是的 - 你可以有两个线程在不同的工作同时变量中的单词。
我的问题很简单;两个不同的线程能否在完全相同的时刻将布尔值设置为真或假?如果不是,为什么不?
如果不是当两个线程同时到达代码时会发生什么,如果它们将布尔值设置为某个值,硬件是否会任意地让一个等待片刻?
或者,如果他们可以,那么最终值是如何确定的?
无论是或否,是否适用于所有类型的变量?
它依赖于实现。它依赖于体系结构。它依赖于处理器负载,依赖于进程调度,几乎依赖于除月相之外的所有事物(我不会把钱花在最后一个上)。
简短的回答是,从长远来看,其中一个线程会成功。在短期内,他们可能对布尔值的实际值有不一致的看法,并且这些观点会在完全不确定(并且可能不一致)的时间段后发生变化。
硬件不会让一个线程等待,因为硬件不会自动知道它们都在同时尝试写入同一内存位置。从长远来看,它可能会注意到这一点,但到那时再做任何巧妙的事情都为时已晚。使用布尔值的线程将是其处理器缓存恰好写回缓存行 second 的线程。毕竟,您的处理器内核并不是每个都直接连接到您的 RAM 芯片。他们必须通过你的内存控制器,而你只有其中之一。
至于是否对所有变量都成立.....嗯。如果变量符合内存字,绝对适用于所有现代计算机体系结构。如果它适合一个缓存行,那么可能。但也有可能,特别是对于较大的结构,一半变量将来自一个线程,另一半来自另一个线程。如果线程正在 更新 内存(例如,将其递增 1)而不是仅 写入 内存(将其设置为它们的线程 ID ,比方说),那么这两个线程成功完成他们计划完成的任务的可能性会进一步降低。
顺便说一句,解决这个错误机会雷区的方法是(按实用性和性能的顺序)(a) 使用同步原语,如互斥锁,(b) 使用原子操作,以及 (c) 一个了解正在发挥作用的线程内存模型。
完全相同的时刻?我怀疑你可能会挑剔到没有这样的东西,除非你指定惯性参考系等等......
如果你是单核,肯定不行。它必须按时间切片 运行 多个线程。
如果你在一个处理器中有多个内核,只有一个数据和地址总线,那么仍然没有。两个进程不可能同时写入内存。处理器必须以特定方式与内存通信,具体取决于内存类型等 - 但基本上你必须设置一个地址,然后执行读取或写入周期来传输数据 - 你不能两个进程这样做。内存管理硬件会让其中之一等待。
如果你有两个处理器,共享内存,那么...仍然没有,如果当时设计系统的人是正确的。
但是从编程的角度来看,它们可以足够接近以至于它们还不如同时进行;使用关键部分或互斥锁或其他任何东西,并使其中一个线程后退一点,而另一个线程则读取、修改、写入。
但是如果你有一个大于你机器的字长的变量(在这个时代可能意味着 > 64 位)或者一个数组变量或类似的东西,那么是的 - 你可以有两个线程在不同的工作同时变量中的单词。