多线程编程 杂谈

多线程获取mutex的先后顺序

当多个线程基本同时到达,但此时mutex被占有时,这些线程获取锁的循序严格按照FIFO

多线程条件变量的唤醒顺序

lock convoy

false sharing

【引用1】
【引用2】
【引用3】

【引用4】

举了一个实际的例子

多线程编程 杂谈_第1张图片

False sharing is a term which applies when threads impact the performance of
each other while modifying 【independent】 variables sharing the same cache line.

两个 cache line 共享同一个 memory line, 由于cache一般采用一致性(MESI、MEOSI)
当 thread0 修改了红色区域时,CPU1中的相应cache line 变为INVALID状态,
当thread1访问蓝色区域时,产生cache miss 

解决方法:


int num __attribute__ ((aligned(CACHE_LINE_SIZE))); (一个变量占据整个CACHE LINE)

CPU cache 效应

引用1
引用2

spurious wakeup

memory barrier

引用1
引用2

程序在运行时内存实际的访问顺序和程序代码编写的访问顺序不一定一致,这就是内存乱序访问。
内存乱序访问行为出现的理由是为了提升程序运行时的性能。
内存乱序访问主要发生在两个阶段:
    1.编译时,编译器优化导致内存乱序访问(指令重排)
    2.运行时,多 CPU 间交互引起内存乱序访问

Processor #1:

 while (f == 0);
 // Memory fence required here
 print x;

Processor #2:

 x = 42;
 // Memory fence required here
 f = 1;

使用场景

1. 实现同步原语(synchronization primitives)
2. 实现无锁数据结构(lock-free data structures)
3. 驱动程序等

volatile 实现

不建议使用

作用

1. 编译后的程序每次需要存储或读取volatile变量时,都会直接从memory中读取数据。
没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值。

2. 对volatile变量的读写不会被优化掉
3. 不做常量合并、常量传播等优化

场景

1. 并行设备的硬件寄存器(如:状态寄存器)
2. 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3. 多线程应用中被几个任务共享的变量

不具有原子性

c/c++的volatile不具备原子语意
Although volatile guarantees that the volatile reads and volatile writes will happen in the exact 
order specified in the source code, the compiler may generate code (or the CPU may re-order execution) 
such that a volatile read or write is reordered with regard to non-volatile reads or writes, 
thus limiting its usefulness as an inter-thread flag or mutex. 
volatile int num = 0;

++num; 
++num : 1.读memory; 2.加1; 3.写回memory 

其他

1. 参数既可以是const还可以是volatile
2. 如下代码,存在问题
int square(volatile int *ptr) { return *ptr * *ptr;  } 

java volatile 引用

wait morphing

你可能感兴趣的:(multi-thread)