wait-free 和 lock-free 资料收集
2011-12-26 15:26
211 查看
等待无关(Wait-Free)/锁无关(Lock-Free)与基于锁(Lock-Based)的比较
一个“等待无关”的程序可以在有限步之内结束,而不管其它线程的相对速度如何。, @% B- m6 I/ O: k0 N7 W f0 [
一个“锁无关”的程序能够确保执行它的所有线程中至少有一个能够继续往下执行。这便意味着有些线程可能会被任意地延迟,然而在每一步都至少有一个线程能够往下执行。因此这个系统作为一个整体总是在“前进”的,尽管有些线程的进度可能不如其它线程来得快。而基于锁的程序则无法提供上述的任何保证。一旦任何线程持有了某个互斥体并处于等待状态,那么其它任何想要获取同一互斥体的线程就只好站着干瞪眼;一般来说,基于锁的算法无法摆脱“死锁”或“活锁”的阴影,前者如两个线程互相等待另一个所占有的互斥体,后者如两个线程都试图去避开另一个线程的锁行为,就像两个在狭窄走廊里面撞了个照面的家伙,都试图去给对方让路,结果像跳交谊舞似的摆来摆去最终还是面对面走不过去。当然,对于我们人来说,遇到这种情况打个哈哈就行了,但处理器却不这么认为,它会不知疲倦地就这样干下去直到你强制重启。
等待无关和锁无关算法的定义意味着它们有更多的优点:
线程中止免疫:杀掉系统中的任何线程都不会导致其它线程被延迟。
信号免疫:C和C++标准禁止在信号或异步中断中调用某些系统例程(如malloc)。如果中断与某个被中断线程同时调用malloc的话,结果就会导致死锁。而锁无关例程则没有这一问题:线程可以自由地互相穿插执行。
优先级倒置免疫:所谓“优先级倒置”就是指一个低优先级线程持有了一个高优先级线程所需要的互斥体。这种微妙的冲突必须由OS内核来解决。而等待无关和锁无关算法则对此免疫。
// WRRMMap的首个锁无关的实现
$ L5 s6 \/ h$ q
// 只有当你有GC的时候才行8 I$ F( {* D# |7 I; I
template <class K, class V>( c% [1 f3 ^8 E) V6 `" c! W) h6 w
class WRRMMap {8 }+ A% E- l7 Q8 T6 f
/ \1 o, e& |- K( q, _ ]' d9 _
Map<K, V>* pMap_;( ?; j2 I! h1 @( z; P
public:3 X5 v+ N( _. B" a* F
V Lookup (const K& k) {
U; ^
// 瞧,没有锁!
; G+ P
return (*pMap_) [k];! s) G2 y8 Y2 J+ i$ z; Q/ b
6 [4 F2 ]/ e+ r/ N: G5 i
}9 Q( s7 O$ ?. d* m0 B' I
void Update(const K& k,
const V& v) {( z% D& k( A. s: V' Z2 V. c
. o5 \# z0 W( h- r8 q
Map<K, V>* pNew = 0;5 c4 j+ P, }' V! U6 d( C
# {% [* t3 k8 {7 o
do {- s, C" f& d. Q0 y; m3 b
. o2 _5 ^: [* B' q4 {- w
Map<K, V>* pOld = pMap_;
p; k/ u Q
delete pNew;
pNew = new Map<K, V>(*pOld);
(*pNew) [k] = v;
} while (!CAS(&pMap_, pOld, pNew));' p- Y4 v, e& ], X' y
+ d- |* k5 f1 I4 w) C) P, N$ g
// 别 delete pMap_;
}. U8 \$ M, F; I# M6 J h
};5 ?6 L, Z5
一个“等待无关”的程序可以在有限步之内结束,而不管其它线程的相对速度如何。, @% B- m6 I/ O: k0 N7 W f0 [
一个“锁无关”的程序能够确保执行它的所有线程中至少有一个能够继续往下执行。这便意味着有些线程可能会被任意地延迟,然而在每一步都至少有一个线程能够往下执行。因此这个系统作为一个整体总是在“前进”的,尽管有些线程的进度可能不如其它线程来得快。而基于锁的程序则无法提供上述的任何保证。一旦任何线程持有了某个互斥体并处于等待状态,那么其它任何想要获取同一互斥体的线程就只好站着干瞪眼;一般来说,基于锁的算法无法摆脱“死锁”或“活锁”的阴影,前者如两个线程互相等待另一个所占有的互斥体,后者如两个线程都试图去避开另一个线程的锁行为,就像两个在狭窄走廊里面撞了个照面的家伙,都试图去给对方让路,结果像跳交谊舞似的摆来摆去最终还是面对面走不过去。当然,对于我们人来说,遇到这种情况打个哈哈就行了,但处理器却不这么认为,它会不知疲倦地就这样干下去直到你强制重启。
等待无关和锁无关算法的定义意味着它们有更多的优点:
线程中止免疫:杀掉系统中的任何线程都不会导致其它线程被延迟。
信号免疫:C和C++标准禁止在信号或异步中断中调用某些系统例程(如malloc)。如果中断与某个被中断线程同时调用malloc的话,结果就会导致死锁。而锁无关例程则没有这一问题:线程可以自由地互相穿插执行。
优先级倒置免疫:所谓“优先级倒置”就是指一个低优先级线程持有了一个高优先级线程所需要的互斥体。这种微妙的冲突必须由OS内核来解决。而等待无关和锁无关算法则对此免疫。
// WRRMMap的首个锁无关的实现
$ L5 s6 \/ h$ q
// 只有当你有GC的时候才行8 I$ F( {* D# |7 I; I
template <class K, class V>( c% [1 f3 ^8 E) V6 `" c! W) h6 w
class WRRMMap {8 }+ A% E- l7 Q8 T6 f
/ \1 o, e& |- K( q, _ ]' d9 _
Map<K, V>* pMap_;( ?; j2 I! h1 @( z; P
public:3 X5 v+ N( _. B" a* F
V Lookup (const K& k) {
U; ^
// 瞧,没有锁!
; G+ P
return (*pMap_) [k];! s) G2 y8 Y2 J+ i$ z; Q/ b
6 [4 F2 ]/ e+ r/ N: G5 i
}9 Q( s7 O$ ?. d* m0 B' I
void Update(const K& k,
const V& v) {( z% D& k( A. s: V' Z2 V. c
. o5 \# z0 W( h- r8 q
Map<K, V>* pNew = 0;5 c4 j+ P, }' V! U6 d( C
# {% [* t3 k8 {7 o
do {- s, C" f& d. Q0 y; m3 b
. o2 _5 ^: [* B' q4 {- w
Map<K, V>* pOld = pMap_;
p; k/ u Q
delete pNew;
pNew = new Map<K, V>(*pOld);
(*pNew) [k] = v;
} while (!CAS(&pMap_, pOld, pNew));' p- Y4 v, e& ], X' y
+ d- |* k5 f1 I4 w) C) P, N$ g
// 别 delete pMap_;
}. U8 \$ M, F; I# M6 J h
};5 ?6 L, Z5
相关文章推荐
- lock-free/wait-free算法以及ABA问题
- lock-free&wait-free
- 关于Lock-free Hash Table的一些链接资料
- 关于Lock-free Hash Table的一些链接资料
- Lock-free VS wait-free
- Lock-free vs. wait-free concurrency
- Spring_错误 java.sql.SQLException: Lock wait timeout exceeded | CannotAcquireLockException 的解决
- FFMPEG视音频编解码资料收集
- (转)无锁编程:Lock-Free Data Structures
- Opengl Volume Rendering 资料收集
- 快速上手Spring--1.收集的一些资料
- ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
- asp 收集的资料了,为了方便查阅。
- 【Java并发编程】2、无锁编程:lock-free原理;CAS;ABA问题
- dedecms专栏----资料收集
- 【Android XMPP】 学习资料收集贴(持续更新)
- github、操作系统 资料收集
- c++中关于文件操作资料收集(外文)
- 资料收集整理
- cocos2d资料收集