基于多线程并发-多线程为什么要加锁

一、线程之间私有和共享的资源

1、私有:
线程栈、寄存器、程序寄存器

2、共享:
堆、地址空间、全局变量、静态变量

二、线程读、写内存数据过程

1、读
1)将内存内容复制到CPU寄存器。load

2、写
1)将内存内容复制到CPU寄存器。load
2)在CPU中增加该值。increment
3)将新值存储在内存中。store

3、将内存内容复制到CPU寄存器
1)根据设定的对齐字节(单次复制的最小值)对内存进行复制。
2)因系统和CPU架构优化等,单次复制的最小值可能远大于该值,但保证该内存连续。

三、为什么需要加锁

1、数据竞争(data race)
1)多个线程访问其共有的资源(堆、全局变量等),需要加锁(互斥锁、读写锁、递归锁等),否则可能存在寄存器和内存数据不一致。
注意: 堆对象的创建分为分配内存、初始化、指针指向该内存,注意锁的细粒度。
2)线程私有资源无需加锁。

2、不同线程的子步骤有顺序关联性
1)示例:

int a = 0;

//Thread1
a = 1;

//Thread2
int b = 10/a;

即线程2中必须等线程1将变量a赋值为1才能对a做除法。
注意: 为条件变量(std::condition_variable)的使用场景。
2)代码顺序不等同程序执行顺序
是因为现在的 CPU 和编译器会尝试对代码进行各种各样的优化,有时候它们可能会为了优化性能而把程序员在写程序时规定的代码执行顺序打乱所导致。

//Thread1
a = 1;
b = 2;

代码"b=2;"可能先于"a=1"运行。

有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

猜你喜欢

转载自blog.csdn.net/qq_43148810/article/details/128815249