发明内容
本发明所要解决的技术问题是在优先级抢占调度的二次调度***中,如何实现锁机制。
本发明的技术方案如下:
一种锁机制的加锁方法,其包括以下步骤:A1、初始化各资源的预约数分别为预设值,用于标记各资源的状态为未预约;A2、申请各资源时,对所申请各资源的预约数进行加一操作,将当前进程相关的锁节点加入到锁等待队列,并判断是否全部申请成功,如果没有全部申请成功则执行A3;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;A3、对于申请失败的各资源,逆向搜索所述锁等待队列,判断在其中是否搜索得到所需的资源,是则在搜索结果相关锁节点的待调度队列标识项,添加当前进程的进程标识,并将搜索得到的资源添加到当前进程相关的锁节点的待申请资源项;A4、判断申请失败的各资源是否全部搜索完成,否则继续执行A3。
所述的加锁方法,其中,步骤A1具体执行以下步骤:设置资源列表,用于管理各资源的预约数;初始化所述资源列表的各资源的预约数分别为预设值;并且,步骤A2中,申请各资源时,是在所述资源列表中,对所申请各资源的预约数进行加一操作。
一种锁机制的解锁方法,其包括以下步骤:B1、按顺序将资源分配给锁等待队列中的锁节点;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;B2、对于某一锁节点所申请的各资源,判断其是否全部申请成功,是则解阻塞其对应的进程,把对应资源的预约数减一。
所述的解锁方法,其中,步骤B1之前还执行以下步骤:B0、判断所述锁等待队列的头节点无效,或者判断事务已经执行到最后,则执行步骤B1。
一种锁机制的实现方法,其包括以下加锁步骤和解锁步骤;
所述加锁步骤包括以下步骤:C1、初始化各资源的预约数分别为预设值,用于标记各资源的状态为未预约;C2、申请各资源时,对所申请各资源的预约数进行加一操作,将当前进程相关的锁节点加入到锁等待队列,并判断是否全部申请成功,如果没有全部申请成功则执行C3;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;C3、对于申请失败的各资源,逆向搜索所述锁等待队列,判断在其中是否搜索得到所需的资源,是则在搜索结果相关锁节点的待调度队列标识项,添加当前进程的进程标识,并将搜索得到的资源添加到当前进程相关的锁节点的待申请资源项;C4、判断申请失败的各资源是否全部搜索完成,否则继续执行C3;
所述解锁步骤包括以下步骤:C5、按顺序将资源分配给锁等待队列中的锁节点;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;C6、对于某一锁节点所申请的各资源,判断其是否全部申请成功,是则解阻塞其对应的进程,把对应资源的预约数减一。
所述的实现方法,其中,步骤C1具体执行以下步骤:设置资源列表,用于管理各资源的预约数;初始化所述资源列表的各资源的预约数分别为预设值;并且,步骤C2中,申请各资源时,是在所述资源列表中,对所申请各资源的预约数进行加一操作;并且,步骤C6中,把对应资源的预约数减一时,是在所述资源列表中,将对应资源的预约数进行减一操作。
所述的实现方法,其中,步骤C5之前还执行以下步骤:C50、判断所述锁等待队列的头节点无效,或者判断事务已经执行到最后,则执行步骤C5。
所述的实现方法,其中,步骤C50之前还执行以下步骤:采用定时监测机制,判断是否超时未响应,是则执行C50。
所述的实现方法,其中,步骤C6中,解阻塞当前锁节点对应的进程之前,还执行以下步骤:判断该进程是否有效,否则不作后续处理。
所述的实现方法,其中,步骤C2至步骤C4的操作,以及步骤C5至步骤C6的操作,分别采用独占任务形式实现。
采用上述方案,本发明提出了不基于信号量等待的锁机制,有效地在优先级抢占二次调度***中,实现了快速锁机制,为事务的并发提供高效的支持。
具体实施方式
以下结合附图和具体实施例,对本发明进行详细说明。
本发明的主旨在于提出一种基于进程二次调度的非信号量锁实现机制,该机制不基于信号量等待;本发明通过为每一个可以加锁的资源维护一个预约数,并且维护一个锁等待队列,来实现上述机制。
如图1所示,本发明提供了一种锁机制的加锁方法,其包括以下步骤:
A1、初始化各资源的预约数分别为预设值,用于标记各资源的状态为未预约;例如,某一资源的预设值为0时,代表该资源的状态为未预约;或者,也可以定义为,某一资源的预设值为1时,代表该资源的状态为未预约;本发明对预设值不作任何限制。
A2、申请各资源时,对所申请各资源的预约数进行加一操作,将当前进程相关的锁节点加入到锁等待队列,并判断是否全部申请成功,否则执行A3。例如,预设值为0时,代表该资源的状态为未预约;当某一进程申请某一资源时,则对该资源的预约数进行加一操作,将其预约数设为1;当另一进程也申请该资源时,则对该资源的预约数再进行加一操作,将其预约数设为2。
其中,所述锁等待队列,也称为解锁集,一个例子如下表所示,其为各锁节点分别设置以下项:进程标识(PID,process identity,即锁定的进程的标识)、待申请资源(WAIT_RES)、申请成功资源(HAVE_RES)和待调度队列标识(PEND_QUE)。
其中,进程标识项用于存储进程标识,以标记该锁节点对应的进程;申请成功资源项用于标记该进程所成功申请得到的资源;待申请资源项用于标记该进程所申请的资源未成功,需等待调度;待调度队列标识项用于标记其它进程的进程标识,表示:当其它进程所申请的资源,被该锁节点对应的进程占用,待该进程执行释放后,将其需要的资源配发给所述其它进程。
假设有9个资源分别为1、2、3、4、5、6、7、8、9,假设进程1首先进行封锁,需要资源为1、2、4、6、9。
LOCK |
WAIT_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
|
A3、对于申请失败的各资源,逆向搜索所述锁等待队列,判断在其中是否搜索得到所需的资源,是则在搜索结果相关锁节点的待调度队列标识项,添加当前进程的进程标识,并将搜索得到的资源添加到当前进程相关的锁节点的待申请资源项。
A4、判断申请失败的各资源是否全部搜索完成,否则继续执行A3。
在具体应用中,可以采用资源列表,管理各资源的预约数,或者管理各资源及其预约数;一个实施例是,步骤A1具体执行以下步骤:设置资源列表,用于管理各资源的预约数;初始化所述资源列表的各资源的预约数分别为预设值;这样,在步骤A2中,当申请各资源时,则在所述资源列表中,对所申请各资源的预约数进行加一操作。
上述的各个实施例,可以分别采用独占任务形式实现。
相应的,如图2所示,本发明提供了一种锁机制的解锁方法,其包括以下步骤:B1、按顺序将资源分配给锁等待队列中的锁节点;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;B2、对于某一锁节点所申请的各资源,判断其是否全部申请成功,是则解阻塞其对应的进程,把对应资源的预约数减一。
一个实施例是,步骤B1之前还执行以下步骤:B0、判断所述锁等待队列的头节点无效,或者判断事务已经执行到最后,则执行步骤B1。又如,在此实施例的基础上,还可以在B0之前在执行以下步骤:采用定时监测机制,判断是否超时未响应,是则执行B0。
又一个实施例是,步骤B2中,解阻塞当前锁节点对应的进程之前,还执行以下步骤:判断该进程是否有效,否则不作后续处理,即无需解阻塞当前锁节点对应的进程及其后续操作。一般来说,可以根据PID判断该进程是否还存在,否则认为其已经失效。
更好的是,同上所述,可以采用资源列表,管理各资源的预约数,或者管理各资源及其预约数;一个实施例是,首先,预设置资源列表,用于管理各资源的预约数;初始化所述资源列表的各资源的预约数分别为预设值;这样,在步骤B2中,当解阻塞对应的进程后,则在所述资源列表中,把对应资源的预约数进行减一操作。
同样的,上述的各个实施例,可以分别采用独占任务形式实现。
综合上述的加锁方法和解锁方法,本发明还提供了一种锁机制的实现方法,其包括以下加锁步骤和解锁步骤。
所述加锁步骤包括以下步骤:
C1、初始化各资源的预约数分别为预设值,用于标记各资源的状态为未预约;同样的,例如,某一资源的预设值为0时,代表该资源的状态为未预约;或者,也可以定义为,某一资源的预设值为100时,代表该资源的状态为未预约;本发明对预设值不作任何限制。
C2、申请各资源时,对所申请各资源的预约数进行加一操作,将当前进程相关的锁节点加入到锁等待队列,并判断是否全部申请成功,否则执行C3;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识;各项含义与上述加锁方法的描述相同,在此不再赘述。
C3、对于申请失败的各资源,逆向搜索所述锁等待队列,判断在其中是否搜索得到所需的资源,是则在搜索结果相关锁节点的待调度队列标识项,添加当前进程的进程标识,并将搜索得到的资源添加到当前进程相关的锁节点的待申请资源项。
C4、判断申请失败的各资源是否全部搜索完成,否则继续执行C3。
其中,步骤C2至步骤C4的操作,可以采用独占任务形式实现。
所述解锁步骤包括以下步骤:
C5、按顺序将资源分配给锁等待队列中的锁节点;其中,所述锁等待队列为各锁节点分别设置以下项:进程标识、待申请资源、申请成功资源和待调度队列标识。
例如,步骤C5之前还可以执行以下步骤:C50、判断所述锁等待队列的头节点无效,或者判断事务已经执行到最后,则执行步骤C5。又如,在此基础上,步骤C50之前还执行以下步骤:采用定时监测机制,判断是否超时未响应,是则执行C50。
C6、对于某一锁节点所申请的各资源,判断其是否全部申请成功,是则解阻塞其对应的进程,把对应资源的预约数减一。例如,在解阻塞当前锁节点对应的进程之前,还执行以下步骤:判断该进程是否有效,否则不作后续处理。
采用资源列表时,一个实施例是,步骤C1具体执行以下步骤:设置资源列表,用于管理各资源的预约数;初始化所述资源列表的各资源的预约数分别为预设值;并且,步骤C2中,申请各资源时,是在所述资源列表中,对所申请各资源的预约数进行加一操作;并且,步骤C6中,把对应资源的预约数减一时,是在所述资源列表中,将对应资源的预约数进行减一操作。
其中,步骤C5至步骤C6的操作,可以采用独占任务形式实现。
以下是本发明所述实现方法的一个完整的例子。
1、加锁流程,如图1所示,其参数包括PID、资源列表。
1)TaskLock;
2)申请所有未预约资源;
3)给资源列表中所有资源的预约数加一;
4)若资源已经完全申请到则TaskUnlock继续事务操作;
5)若资源不满足要求,逆向搜索等待队列中的资源,若某一项含有需要的资源则在该项的解锁集尾部添加自己,直到所有的资源都已经有了通知对象;
7)TaskUnlock;
8)挂起自己。
2.解锁流程,如图2所示,其参数为事务队列中的一项;解锁时机,一般为队头节点无效或者一个事务已经执行到最后。
1)TaskLock;
2)依次将资源列表中的资源分配给解锁集中的锁节点,如果某锁节点已经申请到所有资源,则解阻塞该进程,解阻塞之前可以先判断是否有效,无效则不作处理,把对应资源的预约数减一;
3)TaskUnlock。
实现方法或解锁方法的一个特例是进行死锁检测。
如果某一个进程实例访问了数据库,并且其事务排在事务队列头部,则当该实例被别的进程杀死后,其不能有效解锁释放资源,这样会造成数据库的死锁。
因此本发明引入了定时监测机制,如果队头节点无效,则解锁队头节点。
如果某一个进程实例在队列的中间,则如果其被异常杀死之后,事务并不被删除,需要等到其前面所有事务完成之后才进行解锁,可以由死锁检测机制检测到,这样的情况非常少见,只是采用的一种预防手段。
下面再给出一个具体的例子,对本发明各方法进行详细说明。
假设有9个资源分别为1、2、3、4、5、6、7、8、9;每个资源有一个初始预约数为0。
假设进程1首先进行封锁,其需要资源为1、2、4、6、9。
进程1封锁如下表所示:
LOCK |
WAIT_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
|
进程1需要资源1、2、4、6、9;这时候预约数都为0,所以全部资源均能够得到满足,进程1将资源1、2、4、6、9的预约数加1,封锁完成,事务执行。
假设在进程1未完成的时候,进程2抢占运行,需要资源1、2、5、8。
进程2封锁后如下表所示:
LOCK |
WAIT_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
PID2 |
PID2 |
1,2, |
5,8 |
|
进程2在进程1的事务没有完成的时候来到,这个时候资源5、8的预约数为0,进程2可以申请到资源5、8,但是资源1、2的预约数为1,所以需要等待资源1、2,此时,逆向查找队列中的资源列表,在进程1的锁节点PID1处发现了资源1、2,因此在其该锁节点末尾的待调度队列标识项,添加PID2,将资源1、2、5、8的预约数加1。
假设进程3需要三个资源3、4、8。
进程3封锁后如下表所示:
LOCK |
WAIT_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
PID2,PID3 |
PID2 |
1,2, |
5,8, |
PID3 |
PID3 |
4,8 |
3 |
|
进程3发现资源3的预约数为0,资源4和8的预约数不为0,因此需要等待资源4、8,逆向搜索资源队列,第一次在PID2处找到了资源8,因此把自己的PID的加入到PID2的阻塞队列中,第一次在PID1处找到了资源4,因此把自己的PID加入到PID1的阻塞队列尾。
进程1解锁如下表所示:TASKLOCK;
LOCK |
WAIT_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
PID3 |
PID2 |
|
1,2,5,8, |
PID3 |
PID3 |
4,8 |
3 |
|
进程1执行完成释放,首先找到解锁集中第一个元素PID2,将其需要的资源1、2给他,发现PID2已经可以调入运行,调入。
LOCK |
NEED_RES |
HAVE_RES |
PEND_QUE |
PID1 |
|
1,2,4,6,9 |
|
PID2 |
|
1,2,5,8 |
PID3 |
PID3 |
8 |
4,3 |
|
[0093]接下来取下一次解锁元素PID3,其需要的资源4,PID1可以给出,但是检测其资源并没有完全获取,不作任何动作。
LOCK |
NEED_RES |
HAVE_RES |
PEND_QUE |
PID2 |
|
1,2,5,8, |
PID3 |
PID3 |
8 |
4,3 |
|
将PID1从队列中删除,其所用资源1、2、4、6、9的预约数减一。
TASKUNLOCK。
采用上述方法,有效地在优先级抢占二次调度***中实现快速锁机制,为事务的并发提供高效的支持。
应当理解的是,对本领域普通技术人员来说,可以根据上述说明加以改进或变换,而所有这些改进和变换都应属于本发明所附权利要求的保护范围。