//Lock Versionvoid *producer() { for (i=0; i<loops; ++i){ lock(&m); while (count == MAX) wait(&empty, &m); put(i); signal(&fill); unlock(&m); }}void *consumer() { for (i=0; i<loops; ++i){ lock(&m); while (count==0) wait(&fill, &m); get(i); signal(&empty); unlock(&m); }}
//Semaphore Versionvoid *producer(){ for (i=0; i<loops; ++i){ sem_wait(&emtpy); // It is atomic so it can move here sem_wait(&mutex); put(i); sem_post(&mutex); sem_post(&full); }}void *consumer(){ for (i=0; i<loops; ++i){ sem_wait(&full); // It is atomic so it can move here sem_wait(&mutex); put(i); sem_post(&mutex); sem_wait(&empty); }}sem_init(&empty, 0, MAX);sem_init(&full, 0, 0);sem_init(&mutex, 0, 1);
Reader-Writer Locks
first reader aquires writelock
last reader releases writelock
The Dining Philosophers
big lock (not scalable)
Lock Ordering
add manager
并发 bug
Deadlock: ABBA
Cause
circular dependencies
encapsulation
Live lock: harder to handle
Prevention: 见表格
Avoidance
Scheduling
detect and recover
必要条件
Description
prevention
Remarks
Mutual exclusion(互斥)
一个资源每次只能被一个进程使用
lock-free
powerful hardware instruction
Hold-and-wait(请求与保持)
请求堵塞时不释放已获得的资源
acquiring all lock at a time
No-preemption(不剥夺)
进程已获得的资源不能强行剥夺
release aquired lock
may lead to livelock
Circular wait(循环等待)
若干进程之间形成头尾相接的循环等待资源关系
total/partial ordering on lock acquisition
不让外部调用,调用外部代码时释放锁
原子性违反(AV): ABA
Cause:
临界区间忘记上锁
serialization violated
solution: lock
顺序违反(OV): BA
Cause
order flipped
use after free
solution: condition variables
数据竞争
两个线程对同一个共享变量的非只读并发访问
Event-based Concurrency
解决问题
managing concurrency correctly in multi-threaded application is challenging
has little control over what is scheduled at a given moment in time
event loop
while (1){ events = getEvents(); for (e in events) processEvent(e);}
select/poll
check whether there is any incoming I/O that should be attended to