多处理器编程的艺术 第二版 第八章 笔记

8.1 Introduction

monitor能够同步和数据合并,将各种东西封装起来在一个单个的模块

为什么我们需要这玩意儿?

mutex.lock();
try {
queue.enq(x)
} finally {
mutex.unlock();
}

这个代码不好。因为

1. 调用者根本不知道是否应该调用,因为这个东西的内部大小不可知。

2. 对于多个consumer和producer,每一个都要有一个mutex和queue。

 

不如让队列去管理同步。queue有自己的锁,通过调用这个queue的enq来尝试获取锁,在enq返回的时候释放锁

8.2 Monitor locks and conditions

如果等待时间比较短,spin。如果等半天,建议block。

可以将两者合并一起用。spin只能在多处理器进行。

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit);
    Condition newCondition();
    void unlock();
}

8.2.1 Conditions

对于newCondition()有一个问题。线程被叫醒之后,不一定就满足条件了,还要再次检查。如果不行,就只能再次await了。

我们将方法,互斥锁和condition obj合起来,就叫做monitor了

基本上那些并发工具都是monitor了

8.2.2 The lost-wakeup problem

可能忘记叫醒。

Always signal all processes waiting on a condition, not just one.
Specify a timeout when waiting.

 

8.3 Readers–writers locks

•No thread can acquire the write lock while any thread holds either the write lock
or the read lock.
•No thread can acquire the read lock while any thread holds the write lock.

问题是只有在没有读者才能写,但是读者很多,所以写的一辈子写不了。

 

8.3.2 Fair readers–writers lock

使用了很神奇的设计。让writer进入的时候标注true,然后等待,后面的所有read完成的时候给readRelease++,等一样的时候说明所有的都已经读完了,然后就可以发布消息让writer开始写入。

如果writer醒了,这个时候有writer有reader,先抢锁,等writer一抢到锁别的reader就进不了。

8.4 Our own reentrant lock

进去一次加一个1,出来减1

Semaphore 同理。

总结,可以通过lock加上await的操作,给lock增加各种属性。

 

posted @ 2025-05-29 08:52  映空城  阅读(4)  评论(0)    收藏  举报