Art of Multiprocessor Programming 答案 ch2

来源:互联网 发布:财务审计数据分析报告 编辑:程序博客网 时间:2024/04/30 09:59

自己做的,正确性什么的没有保证。欢迎讨论,欢迎学院派。


一些关于答案的提示:http://courses.csail.mit.edu/6.852/03/handouts/pset5-report.txt


9. 

10. 互斥是通过每个线程看到的各自的view得到关于global的关于critical area的owner的一致看法实现的。根据2.8的证明,锁的实现必须有写的动作,如果第一条指令是读,且只依据这一条指令是不能区分先后的;如果写了之后没有读,线程不能得到view,和没写一样;如果又写又读,并得到某些顺序则它实际就是个gate。

11. 满足互斥。假设不成立。假设 CS(A)-->CS(B)  => R(A)(turn=A) --> R(B)(turn=B) && W(A)(turn=A)-->W(B)(turn=B) && R(A)(turn=A)-->W(B)(turn=B);否则turn由B改变后不能再变成A。所以有 W(A)(busy=true)-->R(A)(turn=A)-->W(B)(turn=B)-->R(B)(busy=false) => W(A)(busy=true)->R(B)(busy=false). 矛盾。

不满足无饥饿,因为某个线程A执行完turn=A之后,等待busy = false的时候,别的线程可能无限次的turn=X-->busy==false-->busy=true。

不满足无死锁。可能有 W(A)(turn=A)-->W(B)(turn=B)-->R(A)(busy=false)-->W(A)(busy=true)-->R(B)(busy=false). A waits turn==A, B waits busy == false.

12.  假设线程A在第k层停住,只要有>2(除A外)个线程进入第k层,到得早的线程必然有 victim != me。

13. 用归纳法。假设k层的这种锁满足互斥,当树高增加到k+1层时,因为Peterson锁满足互斥,使得k+1层上的线程只能在每个k层节点上推举出一个线程,结果是构成一个k层的树,根据假设它满足互斥。同理它也无饥饿。

满足无死锁,因为获得锁的过程是二叉树从叶子节点到跟节点的方向,整个图不能找出任一个有向环,不满足死锁的条件。

上界为n。首先上界>=n(包括自己这一次),否则不满足互斥。假设h=k(根节点h=0)时上界为n=(2^k),当叶节点为2n,h=k+1时,某个叶节点A可能兄弟节点赢,兄弟节点在h=k层上等2^k次加解锁;根据Peterson锁的性质,下次兄弟节点参与竞争是必然是A赢,则A在h=k层上再等待2^k次;即2^(k+1)次,必然得到锁。或者这样考虑,如果一个线程A抢锁成功,则它下一次再参与的时候必然比其它在它第二次抢锁开始之前参与的线程B(包括第一次抢锁)要后得到锁。因为叶结点为n,所以最多有n个线程在它之前。同时,放锁之后下一次抢锁必然输给A。所以界是n。

14. 将filter锁减少l层。根据section 2.4的证明第l层的过程,得知第l层满足l-Exclusion和l-Starvation-Freedom的性质。

15. 不满足互斥。比如2个线程以这个顺序执行lock:W(A)(x=A)-->W(B)(x=B)-->R(A)(y==-1)-->R(B)(y==-1)-->W(A)(y=A)-->W(B)(y=B)-->R(B)(x==B)-->CS(B)-->R(A)(x!=A)-->(A)(lock.lock())-->CS(A)。因为B进入CS时没有经过lock => lock不知道还有一个竞争者 => lock同意A进入CS。而且因为B没有经过lock,它在执行unlock-->lock.unlock()的时候也可能会出问题。

16. 因为W(A)(last = A) -->R(A)(goRight == false)-->W(A)(goRIght = true) --> R(A)(last == A); W(B)(last = B) -->R(B)(goRight == false)-->W(B)(goRIght = true) --> R(B)(last == B);  假设A先,有 W(A)(last = A) --> R(A)(last == A)-->W(B)(last = B) --> R(B)(last == B),也有 W(A)(goRight = true) --> R(A)(last == A) --> W(B)(last = B)--> R(B)(goRight == false)。矛盾。这个过程类似于11题。所以最多只有一个线程获得STOP。

因为任意的线程X都有W(X)(last = X)-->R(X)(last  != X),即对所有的线程X都存在Y使得W(X)(last = X) --> W(Y)(last = Y)。因为在W(X)(last = X)这个点上可以将所有线程按照时间排成完全有序的序列,则随后一个线程找不到比它后来的线程,所以最多只有n-1个得到DOWN。

因为有R(X)(goRIght == true) --> RIGHT(X),而且goRight初始值为false,必然有线程Y: R(Y)(goRight == false)--> W(Y)(goRight = true)。即R(Y)(goRight == false) --> W(Y)(goRIght = true) --> STOP(Y) || DOWN(Y)。所以最多只有一个n-1个线程得到RIGHT。

17. 因为每个Bouncer对象都最多有n-1个线程得到RIGHT,最多n-1个线程得到DOWN,即数组中任意Bouncer对象的右边对象和下面的对象都要比该Bouncer对象少至少一个竞争者。所以线程沿着Bouncer的计算结果移动时,或者得到STOP,或者是剩下的最后一个参与者,也得到STOP。所以必然停在某一个Bouncer。

因为每一步最多有n-1个遗留的线程,但不能确定是往DOWN还是RIGHT,所以得到的布局是如图2-18所示n * n的三角形。

18. 如图所示:

  • A, B在A0上,C在B0上。C观察后准备移到A2,以决定A,B。然后C休眠。
  • B移到A2上
  • A移到A1上
  • A,B在圈A上转,直到A在A1,B在A0。C醒来,转移到A2。A上形成了一个circle。


19. 一个n位2进制的每一位代表一个参与者,1为active,0为inactive。需要一个新label时,假设为线程j,扫描其他n-1个n为2进制数,如果第i个数的第i位为1,表示i为active,并将第j个2进制数的第i位置1,最后将自己的第j位置1。j退出时要将自己的第j位置0,并将其他数的第j位置0。
证明n*2^n够用等,见Ref[77]:https://www.google.com.hk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCoQFjAA&url=https%3A%2F%2Fcs.uwaterloo.ca%2F~mli%2Famos.ps&ei=ZQuUUtOGEpTIkAec7oCACg&usg=AFQjCNE2qAO_mGBIHrBJjZqfXDxHs7Hffw

原创粉丝点击