一、并发程序的状态机模型
全局区和堆区共享,栈区线程独有。通过栈区切换线程执行交替,实现并发。
1、并发的基本单位:线程
共享内存的多个执行流
执行流拥有独立的堆栈指针/寄存器
共享全部的内存(指针可以互相引用)
二、线程库thread.h
1、create(fn)
创建一个函数入口是fn的线程,并立即开始执行
void fn(int tid){...}
参数tid从1开始编号
语义:在状态中新增stack frame列表并初始化为fn(tid)
1、join()
等待所有运行的线程的fn返回
在main函数返回时会自动等待所有线程结束
语义:在有其他线程未执行时死循环,否则返回
三、多线程带来的麻烦
1、多核多线程访问全局公共资源,会出现错误。如同时判断值大小,就会同时进入if中
long a;
thread1()
{
if(a > 1)
{
a-=1;
}
}
thread2()
{
if(a > 1)
{
a-=1;
}
}
通过
lock(&lk)
unlock(&lk)
实现对临界资源的互斥操作
2、编译器优化不顺序的多线程程序
编译器会优化不夹杂系统调用(syscall)的连续操作,如
thread1:
if(i==0)
{
i++;
i++;
}
thread2:
if(i==0)
{
i++;
i++;
}
会被优化成
thread1
if(1==0)
{
i+=2;
}
thread2
if(1==0)
{
i+=2;
}
当编译器优化多线程程序,就会出现问题
四、总结
1、多处理器编程
多处理器程序=状态机(共享内存;非确定选择线程执行)
2、多处理器编程,放弃对程序的旧理解
不原子,能乱序,不立即可见
来自于编译器优化(处理器也是编译器)