一、CMB算法简介
CMB算法是最早的保守同步算法,其基本思想为逻辑处理单元之间的消息按非递减的顺序发送,消息接收者为每一个连接维护一个队列来保存收到的消息。每个队列都有一个时间戳,为队列中的消息时间戳最小的,如果队列为空则是最后一个收到的消息的时间戳。
算法步骤:
(1).找出所有队列中时钟值最小的队列。
(2).如果该队列中有消息,则取出消息并处理,转(1)。
(3).如果该队列中没有消息,则阻塞等待直到这个连接上有一个新的消息来临。
(4).新的消息将该队列的时间戳更新,转(1)。
二、死锁的处理
CMB算法容易造成死锁,以下图为例
对lp1来说,时间戳最小的队列为lp3的信道,但是此信道为空,所以lp1阻塞;对lp3来说最小的队列为lp2的信道,但此信道为空,所以lp3也是需要阻塞等待;同样对于lp2来说最小的时间戳是lp1的信道,此信道为空,所以LP2阻塞等待。
CMB是利用空消息来进行避免死锁的,空消息是指没有真实的数据而仅携带时间戳的消息,该时间戳给出了本LP以后发出的消息的时间戳的底限,在收到一个空消息之后,接收LP可以将该连接上的时间戳更新到这个时刻,从而使得该LP可以重新选择时间戳最小的队列,系统得以继续向前推进。
LP在发送空消息时,空消息携带的时间戳是由本地Cycle+LookHead(LookHead不能为零,如果为0,则是不能解决死锁问题的),LookHead是逻辑处理单元根据当前时钟值,结合事件处理所需的时间,给出的下一个即将从该逻辑处理单元发出的消息的时间戳的下限,此下限跟当前时钟的差值就是LookHead的值。
以上图为例,如果LookHead值为0,则发送完空消息之后的情况为:
在发送空消息仍然处于死锁状态。
Lp1根据当前时钟值,结合事件处理所需时间,发送的空消息的时间戳可能是10,lp2发送的可能是8,Lp3发送的可能是11,因此发送完空消息之后的情况为:
则系统可以继续执行。