共享内存和分布式内存模型回顾
Cache协同
程序员无法控制cache,但是可以通过控制访存模式来更好的利用Cache。
基于侦听的Cache协同
- 核心共享总线——总线上的信号可以被所有核心所看到。
- 如果有核心更新了缓存中的共享变量副本,广播到总线上;其他核心将Cache中的共享变量副本无效。
问题:效率低。
基于目录的Cache协同
- 使用目录保存每个核心Cache使用的变量。
- 共享变量更新之后,遍历目录寻找核心更新。
问题:目录本身就是一个共享变量,效率也比较低;实际应用中往往是分布式存储。
共享内存互联
总线
同一个时刻只有一个CPU可以访问内存。
适用于连接到总线的设备比较少。
最简单、便宜并且易于实现。
效率低。
交换互联
使用交换开关控制数据在设备中的路由。
共享内存编程
有以下两个模式:
- 动态线程
即用即创(有一个主线程,fork创建子线程)。
资源利用率较高,但是线程的创建和结束非常耗时。 - 静态线程
线程池。
性能更优,但是可能浪费资源。
线程安全
定义:对于一个函数或者库,如果可以多线程并行调用且正确执行,那么说该函数或者库是线程安全的。
POSIX Threads编程简介
基础API介绍
int pthread_create(pthread_t *, const pthread_attr *, void* (*)(void*), void *);
解释:主线程借助操作系统创建一个新线程。第一个参数是线程ID或者句柄,第二个参数是线程的各种属性,一般情况下是空的;第三个参数是命令线程需要运行的函数;第四个参数是传递给函数的参数。
注意:创建线程的代价非常高,因此需要函数工作量较大的时候才值得付出这种代价。
int pthread_join(pthread_t *, void **value_ptr);
挂起该线程,直到传入的目标线程已经结束。
第二个参数允许向目标线程返回一些信息,一般为NULL。