Operating Systems: Three Easy Pieces阅读笔记(二)concurrence-lock&condition val&semaphores

来源:互联网 发布:android开发计算器源码 编辑:程序博客网 时间:2024/06/14 10:23

concurrence:

lock
1。不能用简单的flag(如int的0、1置换)实现lock,原因在于实现lock的过程本身就不是原子操作,存在被打断的可能。
2。spin lock
过于浪费cpu时间片,在已有线程获取锁的情况下,其余线程只能消耗光一个时间片
3。Lock With Queues, Test-and-set, Yield, And Wakeup
首先用上述的spin lock(guard)将lock 和 unlock操作作为critical section包覆起来。
获取lock 的线程,如果队列不为空,则直接将lock传递到队首的线程(直接唤醒);如果队列为空,则直接释放lock。
对于未能获得lock的的线程,先调用setpark()防止释放guard后,l被中断并且释放了lock,导致park()永久睡眠,然后释放guard,并且调用park()释放cpu,当被唤醒时,从park返回继续执行后续指令(此时上一个线程获得的lock未被释放,unlock时则同上)。
队列保证了队中的线程在未来某一时刻会被唤醒,避免了某一线程持续饥饿
lock后并不是表示线程不可中断,而是使用同一把锁的线程不能再执行lock()和unlock()之间的命令,从而保护线程共享的资源。


Condition Variables(CV)

    pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m);    假定当前已获得锁m,释放锁m,等待信号c,线程阻塞。    当线程被唤醒时,如果获得了目标信号c,则重新获得锁m。    注意在释放锁和重新获得锁之间由于其他线程并发而引起的bug。    pthread_cond_signal(pthread_cond_t *c);    释放信号c并唤醒等待该信号的线程。    使用信号的通常形式:    等待线程    pthread_mutex_lock(&mtLock);    while (flag== 0)        pthread_cond_wait(&mtCond, &mtLock);    pthread_mutex_unlock(&mtLock);    信号线程    pthread_mutex_lock(&mtLock);    flag= 1;    pthread_cond_signal(&mtCond);    pthread_mutex_unlock(&mtLock);    flag的作用是表示信号是否已经释放,以防wait()在signal()之后调用而永远阻塞,使用锁以防当等待线程在判断flag==0后,调用wait()前切换至信号线程释放信号,同样导致等待线程永远阻塞

Semaphores

         #include <semaphore.h>         2 sem_t s;         3 sem_init(&s, 0, 1);

第二个参数为0表示用于线程并发。
第三个参数代表了s的一个value,该value>=0可看作当前可用的“资源数”,并且在调用sem_wait()时线程立即返回,否则阻塞。当value<0,表示在等待的线程数。摘自书上:

First, we can see that sem_wait() will either return right away (because the value of the semaphore was one or higher when we called sem_wait())

sem_wait()的作用如上所述,调用时先将value值减少一再进行判断value是否大于0,sem_post()则将value值增加一(负等待的线程数减少,或表示可用的资源数增加),并唤醒等待的线程

0 0