为什么多线程中的Local / Stack变量不需要锁定

时间:2012-09-23 10:22:17

标签: c++ multithreading

我从事过多线程(在Qt中),但我缺乏深入的知识。我认为运行时永远不会复制执行代码。函数将保留在一个内存位置,所有调用者或对象将使用它来调用它。在多线程中,我读到每个线程都有自己的堆栈,指令指针等等。假设我们有一个全局函数,它转换为这样的汇编算法:

//GlobalFunction()
instruction 1 : move value 4 into accumulator
instruction 2 : add 5 to content of accumulator
instruction 3 : subtract 1 from content of accumulator
//some more stuff and function returns

//thread 1
call GlobalFunction()

//thread 2
call GlobalFunction()

现在也许线程1的指令指针指向指令3,而线程2获得切片并执行指令1.此线程1执行指令3.不会累积器数据被破坏吗?如果是这样,为什么仅使用非静态局部变量的函数不需要在多线程环境中锁定?

P.S:我还假设一条指令是原子而不是一组指令,因此在执行另一个线程的指令之前,实现可能无法将寄存器数据刷出到某个存储位置。

3 个答案:

答案 0 :(得分:7)

虽然CPU上只有一组寄存器(为简单起见,我假设是一个单核系统),系统管理寄存器文件,使每个线程都有自己独立的寄存器状态 - 当操作系统从一个线程到另一个线程,第一个线程的寄存器被保存,第二个线程的保存寄存器被恢复。

对于自动/堆栈变量,每个线程获得它自己的堆栈,所以除非线程做某事明确共享这样的变量(通过传递地址或引用到另一个线程),这些变量不会被共享,所以线程 - 安全

答案 1 :(得分:2)

OS和CPU处理寄存器和各种CPU状态。多核CPU具有多个累加器/寄存器 - 每个活动线程一个。单核CPU不能在指令中间中断 - 整个可见的CPU状态在寄存器中,由OS保存和恢复。

答案 2 :(得分:0)

不,每个线程也有自己的执行寄存器(包括处理器可能具有的任何累加器)。

在多处理器系统上,每个处理器都有自己的寄存器(这是使其成为独立处理器的核心),当多个线程切换到同一处理器时,寄存器状态被保存。恢复。