【操作系统】顺序性,可见性,原子性概念

顺序性: 例如这几行代码,前面三行代码的赋值操作没有意义,cpu可能直接把代码有化成int ii=50
可见性:
原子操作:

例如i++,cpu执行这行代码分三个步骤

  1. 从内存中读取i的值
  2. 把i+1
  3. 把i的值写回内存 这三个步骤不是一气呵成,中间可能会被打断,例如某个线程在执行到其中一个步骤的时候,如果自己的CPU事件片用完了,就会被操作系统切换出去,当这个线程再次获得时间片的时候,黄花菜都凉了

在一台多核系统中,以下代码aa不会得到200w,如果在单核,则会得到200w

#include <iostream>
#include <thread>        // 线程类头文件。
using namespace std;

int aa = 0;     // 定义全局变量。

// 普通函数,把全局变量aa加1000000次。
void func() {
	for (int ii = 1; ii <= 1000000; ii++)
		aa++;
}

int main()
{
	// 用普通函数创建线程。
	thread t1(func);     // 创建线程t1,把全局变量aa加1000000次。
	thread t2(func);     // 创建线程t2,把全局变量aa加1000000次。

	t1.join();         // 回收线程t1的资源。
	t2.join();         // 回收线程t2的资源。

	cout << "aa=" << aa << endl;   // 显示全局变量aa的值。
}

这是因为在多核系统中,每个线程可能被分配到不同的核心上执行,全局变量aa的读写可能会引发多个线程之间的竞争条件,导致结果不准确。

具体来说,在多核系统中,每个线程可能被分配到不同的核心上执行,当多个线程同时访问全局变量aa时,就会出现竞争条件。例如,线程1读取全局变量aa的值为10,线程2也读取全局变量aa的值为10,线程1增加aa的值为11,线程2也增加aa的值为11,最终全局变量aa的值只增加了1次,而不是2次。因此,最终的结果不是200w,而是小于200w的值。

经验分享 程序员 微信小程序 职场和发展