为了很好的利用多核处理器的性能,并行开发的收益也随之越来越高,为此针对多线程作了一些总结
1,临界区:
临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时,其他线程或是进程必须等待。(加锁就是限制临界区的访问)
2,锁
死锁(A-B-C-D-A-B-C-D...);
活锁(面对面让路问题,通常因为处理死锁问题不当所产生的);
饥饿(是一个线程长时间得不到需要的资源而不能执行的现象);
3,并发级别
由于临界区的存在,多线程之间的并发必须受到控制,根据控制并发的策略,我们可以把并发的级别分类,大致上可以分为阻塞,无饥饿,无障碍、无锁、无等待五种
阻塞:如果临界区被上锁,其他线程因为得不到锁就会被挂起等待的模式。
无饥饿:就是摒弃线程的优先级,让所有的线程公平排队,让所有线程都有机会执行
无障碍:无障碍的思想就是让所有线程都可以进入临界区,如果共享数据被修改坏,系统一旦检测到这种情况,就会立即对自己所做的修改进行回滚,确保数据安全。但是如果没有数据竞争发生,那么线程就可以顺利完成自己的工作,走出临界区。但是当临界区存在严重冲突时,所有的线程可能都会不断的回滚自己的操作,导致没有一个线程能顺利走出临界区。这种情况会影响系统的正常执行。
无锁:无锁的并行都是无障碍的。在无锁的情况下,所有的线程都能尝试对临界区进行访问,但不同的是,无锁的并发保证必然有一个线程能够在有限步内完成操作走出临界区。java的原子类就是采用这种策略
无等待:无等待是对无锁的一种扩展,他的思想就是保障所有的线程在有限步数内完成,可以解决饿死的问题。java中的实现就是一些并发容器的实现(读线程无等待,写时复制无等待,回写最终数据)
4,Amdahl(阿姆达尔定律)
s-加速比,n-处理器个数,F- 串行比例
S=1/(F+(1-f)/ n)
阿姆达尔定律的核心思想就是,如果程序本身并发模块过少,那么增加处理器个数所带来的收益是和成本不成比例的
举一个极端的例子,处理器增加五个,串行比例F为1,S = 1;(相当于没加速)
如果我们把并行比增加到0.5,处理器个数任然为5 S最终可为1/(0.5+0.5/5)=1.6
所以权衡收益和成本是至关重要的,另外增加程序的并行模块占比
5,Gustafson定律(古斯塔夫森定律)
S-加速比,n-处理器个数,F- 串行比例
S = n-F(n-1)
这个定律的核心思想就是如果并行比例足够,那么加速比是和CPU个数呈线性关系。