Multithreading 在具有一个CPU核心的多线程上真的需要计数锁吗?

Multithreading 在具有一个CPU核心的多线程上真的需要计数锁吗?,multithreading,operating-system,thread-safety,locking,multiprocessing,Multithreading,Operating System,Thread Safety,Locking,Multiprocessing,如果我有一些代码是这样的(请忽略语法,我想在没有指定语言的情况下理解它): 这里我有一个只有一个内核的CPU,我真的需要一个变量count的锁,以防它被其他线程重写 我不知道,但是如果语言很重要,请在Java、C和Python下解释,非常感谢 谢谢你们,我现在知道我需要一把锁了。但这里还有一个问题,我什么时候需要使用多线程 由于CPU只执行一个指令,多线程似乎需要更多的时间来管理线程切换,并且无法节省计算时间。从技术上讲,通常是这样。也许在这个特殊的例子中没有。但是想象一下,你的原子函数将由几

如果我有一些代码是这样的(请忽略语法,我想在没有指定语言的情况下理解它):

这里我有一个只有一个内核的CPU,我真的需要一个变量count的锁,以防它被其他线程重写

我不知道,但是如果语言很重要,请在Java、C和Python下解释,非常感谢


谢谢你们,我现在知道我需要一把锁了。但这里还有一个问题,我什么时候需要使用多线程


由于CPU只执行一个指令,多线程似乎需要更多的时间来管理线程切换,并且无法节省计算时间。

从技术上讲,通常是这样。也许在这个特殊的例子中没有。但是想象一下,你的原子函数将由几个指令组成。操作系统可以并且确实一次执行多个线程。它执行其中的一些步骤,然后切换回选择要继续的进程/线程的操作系统。它可以启动所有线程并在它们之间切换。甚至在一个CPU上。然后所有线程将在相同的内存地址上运行并共享变量

编辑:回答第二个问题。 当您有一个内核时,我只能想象一种需要多线程的情况。此时,您的一个线程可以锁定,您需要对其进行监视或执行其他操作。一个实际的例子是服务器。如果你想同时为多个客户服务,你需要在他们之间切换。如果您在队列中为他们服务,一个坏客户机可能会挂起整个过程


如果您正在进行计算,您可以使用它来拆分I/O和计算。但它必须是一个非常极端的情况才能有用或需要。

从技术上讲,一般来说是的。也许在这个特殊的例子中没有。但是想象一下,你的原子函数将由几个指令组成。操作系统可以并且确实一次执行多个线程。它执行其中的一些步骤,然后切换回选择要继续的进程/线程的操作系统。它可以启动所有线程并在它们之间切换。甚至在一个CPU上。然后所有线程将在相同的内存地址上运行并共享变量

编辑:回答第二个问题。 当您有一个内核时,我只能想象一种需要多线程的情况。此时,您的一个线程可以锁定,您需要对其进行监视或执行其他操作。一个实际的例子是服务器。如果你想同时为多个客户服务,你需要在他们之间切换。如果您在队列中为他们服务,一个坏客户机可能会挂起整个过程


如果您正在进行计算,您可以使用它来拆分I/O和计算。但它必须是一个非常极端的情况才能有用或需要。

对于最简单的示例,我们创建了多个线程,共享一个变量,并对其执行单个原子指令。无论在何处中断任何线程,其状态都是在共享资源上的指令之前或之后


在这种情况下,x86增量是原子的,因此是线程安全的。您不需要锁来保持一致性或幂等性

对于最简单的示例,我们创建多个线程,共享一个变量并对其执行一条原子指令。无论在何处中断任何线程,其状态都是在共享资源上的指令之前或之后


在这种情况下,x86增量是原子的,因此是线程安全的。您不需要锁来保持一致性或幂等性

是的,你可能还需要一把锁。您的
倒计时
代码可能编译为以下内容:

load global variable "count" into register x
x = x + 1
save register x into global variable "count"
如果中间有一个螺纹开关,那你就有麻烦了。实际上,你不需要第二个核心来获得不良行为


有时,
倒计时
可能编译为原子指令。例如,在x86上有这样的指令,但我无法保证编译器使用它们(除了自己编写程序集)。

是的,您可能仍然需要一个锁。您的
倒计时
代码可能编译为以下内容:

load global variable "count" into register x
x = x + 1
save register x into global variable "count"
如果中间有一个螺纹开关,那你就有麻烦了。实际上,你不需要第二个核心来获得不良行为


有时,
倒计时
可能编译为原子指令。例如,
x86
上有这样的指令,但我无法保证编译器使用它们(除了自己编写程序集)。

对于诸如递增计数器之类的简单操作,而不是使用锁,在c中,可以找到以线程安全方式执行操作的原子函数。GCC定义了这些原子内置函数,这些函数通常封装在特定环境中的公共函数调用中

例如,MacOSX定义了这些


它们有可能比锁更有效,因为它们的功能比锁更有限。

对于简单的事情,如递增计数器,而不是使用锁,在c中,您可以找到以线程安全方式执行操作的原子函数。GCC定义了这些原子内置函数,这些函数通常封装在特定环境中的公共函数调用中

例如,MacOSX定义了这些


它们有可能比锁更高效,因为它们的功能比锁更有限。

什么时候需要多线程

对我来说,有两种不同的应用:

  • 并行处理是指多个线程(理想情况下每个核心只有一个线程)在较长时间内处理整个问题的一小部分。所需的代码和数据很小,即使在最好的情况下,也适合于