伪代码中屏障节点用 b 表示,每个客户端进程(节点) p 在进入屏障节点时注册事件,然后在离开时取消注册事件。进入屏障节点注册事件的代码如下表的 Enter 程序段所示, 在继续处理任务之前,它将等待客户端 x 进程的注册。(此处的 x 由你针对自己的系统决定)
EnterLeave
创建名称为 b+“/”+p 的 Znode 节点
设置监视:exists(b + ‘‘/ready’’, true)
创建子节点:create( n, EPHEMERAL)
L = getChildren(b, false)
如果L的孩子数目小于 x 的, 则等待监视事件
否则 create(b + ‘‘/ready’’, REGULAR)
L = getChildren(b, false)
如果没有任何子节点,则退出。
如果 p 是 L 中唯一节点,则 delete(n) 并退出。
如果 p 是 L 中的序号最低的节点,则等待 P 中的序号最高节点。
否则 依然存在,则 delete(n) 并继续等待L中的最低节点。
跳转 1
在进入屏障时,所有的进程(节点)监视一个准备好的节点(屏障节点),并创建一个临时节点作为屏障节点的孩子。除了最后进入屏障的节点外,每个进程(节点)都等待屏障节点,直到第 5 行的条件出现。该进程(节点)创建第 x 个节点——即最后的进程(节点),它将会看到 x 个节点,并唤醒其他进程(节点),注意,所有的等待进程(节点)只是在退出的时候被唤醒,所以等待还是很高效的。
当 b 没有的进程子节点时,进程(节点)就会退出屏障区。然而,为了效率起见,你可以使用序号最低的进程节点作为 ready 标志。所有其他准备退出屏障区的进程(节点)都监视序号最低的将要退出进程(节点)消失,序号最低的进程节点的拥有者则就等待其他任何一个节点的消失(选择序号最高进程节点)。这意味着除了最后的一个进程节点外,其他的每个进程节点被删除时只要唤醒一个进程节点即可,当它被删除时就会唤醒其他的进程节点。
获取读锁:获取写锁:
Call create( ) to create a node with pathname "_locknode_/read-". This is the lock node use later in the protocol. Make sure to set both the sequence and ephemeral flags.
Call getChildren( ) on the lock node without setting the watch flag - this is important, as it avoids the herd effect.
If there are no children with a pathname starting with "write-" and having a lower sequence number than the node created in step 1, the client has the lock and can exit the protocol.
Otherwise, call exists( ), with watch flag, set on the node in lock directory with pathname staring with "write-" having the next lowest sequence number.
If exists( ) returns false, goto step 2.
Otherwise, wait for a notification for the pathname from the previous step before going to step 2
Call create( ) to create a node with pathname "_locknode_/write-". This is the lock node spoken of later in the protocol. Make sure to set both sequence and ephemeral flags.
Call getChildren( ) on the lock node without setting the watch flag - this is important, as it avoids the herd effect.
If there are no children with a lower sequence number than the node created in step 1, the client has the lock and the client exits the protocol.
Call exists( ), with watch flag set, on the node with the pathname that has the next lowest sequence number.
If exists( ) returns false, goto step 2. Otherwise, wait for a notification for the pathname from the previous step before going to step 2.