实现公平可缩放的读者写者互斥的方法和装置的制作方法

文档序号:6376125阅读:116来源:国知局
专利名称:实现公平可缩放的读者写者互斥的方法和装置的制作方法
技术领域
本发明一般地涉及多线程编程,尤其涉及在多线程编程环境下 读者(reader)与写者(writer)的互斥(mutual exclusion)。
背景技术
互斥是一种编程技术,其通常通过使用信息量(semaphore)来确保同一时刻只有一个程序或例程可以访问某些资源,例如存储器位置、输入/输出(I/O)端口或文件,其中信息量是程序中用以协调一个以上程序或例程活动的标志。用于执行互斥(或互斥体(mutex))的对象可称为一个锁定(lock)。读者-写者(RW)锁定允许多个读者查阅共享数据,或者允许单个写者排他地访问以修改此数据。在共享存储器的多处理器上,获得和释放这些锁定所需的开销对并行应用程序的性能有很大的影响。这些锁定初级实现(na'iveimplementation )(其中处理器绕全局锁定变量旋转以等待锁定变为可用)的主要问题,是当所述锁定被竞争时,包含所述锁定的存储器以及连接到该存储器的互连网络也会被竞争。现有技术的各种方法实现可缩放的排他锁定,即能够被竞争而不导致存储器或者互连竞争的排他锁定。这些方法取决于高速缓存硬件支持或者本地存储器的存在,其中访问本地存储器的等待时间低于访问远程存储器的等待时间。在1991年4月在弗吉尼亚州威廉斯堡举行的第三届有关并行程序的原理和实践的 ACM 研讨会文集第 106-113 页(Proceedings ofthe 3rd ACM Symposium on Principleand Practice of Parallel Programming, pp. 106-113, Williamsburg, VA, April 1991)由 John M.Mellor-Crummey 和 Michael L. Scott 发表的“Scalable Reader-ffriterSynchronization for Shared-Memory Multiprocessors”一文中,作者描述了一种使用原子运算以建立等待处理器的单链表(singly linked list)的排他锁定。列表首部的处理器拥有该锁定,而新处理器则将自己加入列表尾部。与在绕全局锁定变量旋转不同,每一处理器在其本地存储器内绕一个变量旋转。处理器通过归零该变量来释放所述锁定,而下一个处理器在绕该变量旋转的队列中排队。对于这种排他锁定的RW变量,每一队列元素包括一附加的变量来保存请求的状态。当新的读者请求达到时,就检查队列中前一元素的状态以确定新请求是否必须阻止。有了 RW锁定,读者必须能够以任何顺序释放锁定。因此,当读者出队时,Mellor-Crummey和Soctt的单链表变得不连续。为了允许这种状况,在他们的排他锁定中加入两个全局变量,一个是活动读者数量的计数,一个是队列中第一写者的指针。当读者获得和释放锁定时,它们保持活动读者的全局计数最新。当释放锁定时,如果读者发现读者计数为零,其解除对全局变量指向的写者的阻止。在1993年有关并行进程的国际会议文集(Proceedings of the1993International Conference on Parallel Processing)中由 Orran Krieger、MichaelStumm、Ron Unrau 和 Jonathan Hanna 发表的 “A Fair Fast Scalable Reader-ffriterLock” 一文中,作者描述了一种从Mellor-Crummey和Scott的排他锁定算法中导出的公平可缩放的RW锁定算法。在Krieger等人的方法中,并不是加入更多的全局状态(其可变为被竞争),而是把RW锁定需要的额外状态在与该锁定关联的列表中分配。更具体地,读者 被保持在双链表(doubly linked list)中。利用双链表,代替对全局变量的同步,正在释放锁定的读者可与其最近的邻近读者同步以从队列中移除其本身。这允许读者以任何顺序出队而列表也不会变得不连续。因此,不必保持对第一写者的全局指针,也不必保持对活动读者数量的全局计数。上面讨论的两种现有技术至少存在各种不足。在上述的每一方法中,不能将队列节点分配在栈中,因为有时调用者提供的队列节点会被其他线程读取或写入,甚至在调用者释放了互斥体上它的锁定之后。这些方法要求将队列节点分配在堆(heap)中,这比栈分配慢,并且可能需要获得该堆本身上的其他锁定。此外,这些方法要求队列节点在互斥体的生存期内永不被释放,也不能以某种方式被原子性地参考计数以确定何时释放它们是安全的(这在多线程环境中相比普通的读和写是开销巨大的)。这些方法还要求队列节点存在的时间比获得和释放锁定之间的时间更长。另外,Krieger等人的方法中,当读者在其前任已经观察到没有后继者可以解除阻止时预期会被其前任解除阻止时,有时允许读者阻止其他读者,这导致读者阻止直到所有之前的读者释放互斥体。因此,多线程编程技术需要进一步改进以克服这些和其他缺陷。

发明内容
本发明提出了一种实现公平可缩放的读者写者互斥以便由处理系统中多个处理线程访问临界段的方法,所述方法包括为第一线程在所述第一线程的栈上创建第一队列节点,所述队列节点表示所述第一线程访问所述临界段的请求;将所述第一队列节点加入由用于所述临界段的单字读者写者互斥体指向的队列,所述队列表示期望访问所述临界段的线程列表,所述队列中的每一队列节点位于所述多个处理线程中的一线程的栈上;等待直到由所述队列上的先前队列节点指示所述第一队列节点没有在前的写入请求;由所述第一线程进入所述临界段;以及在所述第一线程退出所述临界段之后,从所述队列中移除所述第一队列节点,其中,作为读者的线程绝不阻止作为读者的另一线程。本发明还提供了一种用于实现公平可缩放的读者写者互斥体以便由处理系统中多个处理线程访问临界段的装置,所述装置包括用于为第一线程在所述第一线程的栈上创建第一队列节点的装置,所述第一队列节点表示由所述第一线程对访问所述临界段的请求;用于将所述第一队列节点加入由用于所述临界段的单字读者写者互斥体指向的队列的装置,所述队列表示期望访问所述临界段的线程列表,所述队列中的每一队列节点位于所述多个处理线程中的一线程的栈上;用于等待直到由所述队列上的先前队列节点指示所述第一队列节点没有在前的写入请求的装置;用于由所述第一线程进入所述临界段的装置;以及用于在所述第一线程退出所述临界段之后从所述队列中移除所述第一队列节点的装置,其中,作为读者的线程绝不阻止作为读者的另一线程。


通过下面的本发明的详细描述,本发明的特征和优点将会变得显而易见,其附图中图I是根据本发明一个实施例的读者写者互斥体的示例性队列的示意图;图2是根据本发明一个实施例的队列节点的示意图;图3是根据本发明一个实施例的使用具有读者写者互斥体的队列的流程图; 图4是根据本发明一个实施例并详细示出队列节点值的图I所示示例性队列的示意图;以及图5是根据本发明一个实施例示出队列节点状态值UnblockNext的使用的示意图。
具体实施例方式本发明的一个实施例是一个读者-写者互斥体过程,该过程以克服在前读者-写者互斥体缺陷的方式实施读者和写者的互斥。处理线程在进入一临界段之前获得互斥体上的“读者锁定”或“写者锁定”,并在之后释放它们的锁定。互斥体的工作是确保若一写者在临界段(critical section)中,则该写者就是那里唯一的线程。典型地,读者-写者互斥体起到保护数据结构一致性的作用。希望修改此结构的线程只有在获得写者锁定之后才能这么做。读者-写者互斥体优于普通互斥体之处在于多个读者可同时进行,因此重要的是读者绝不阻止读者。本说明书中引用本发明的“一个实施例”或“一实施例”意思是连同该实施例一起描述的特定特征、结构或特性是包含在本发明的至少一实施例中。于是,在本说明书中的不同位置多次出现的短语“在一个实施例中”并不一定指代同一实施例。一线程在其进入临界段前可能不得不等待其他线程离开。本发明是“公平的”是因为它以“先到先服务”的顺序服务于线程,这确保没有线程会被阻延而一直等待。等待中的线程不应该消耗存储器带宽;否则它会减慢其他线程。等待通过“本地旋转”来完成,这意味着读取一个没有其他处理器会频繁接触的高速缓存线,直到其他线程更新此高速缓存线以告知“继续进行”。RW互斥体可利用队列来实现。此队列包括零或更多个根据需要建立和销毁的队列节点。此互斥体包括指向队列尾部的单字(word)。在本发明的实施例以及此处的使用中,“字”定义处理系统中需要用以储存指针值的存储器容量。当处理线程要求对互斥体保护的临界段进行读或写访问时,它们会将请求放到该队列上。访问请求由队列节点表示。每一线程提供将绕其旋转的队列节点。当队列节点位于队列首部时,创建此队列节点的线程会被授权访问该临界段。在本发明的一个实施例中,在线程的栈上创建队列节点。RW互斥体指向队列的尾部以指示下一个希望访问临界段的线程可被链接到哪里。
图I是根据本发明一个实施例的读者写者互斥体的示例性队列的示意图。图I示出处于不同阶段的4个线程。线程1100和线程2102是临界段内部的读者。线程1100包括栈104。线程I已于之前在其堆栈104中创建队列节点1106。队列节点1106目前是用于读者写者互斥体108的队列的首部。线程I还包括指令指针110以指定正在被此线程执行的当前指令。当线程I在临界段内时,指令指针引用临界段内的存储器。类似地,线程2102包括栈112。线程2已于之前在其栈112内创建队列节点2114并链接队列节点2到用于RW互斥体的队列中。线程2还包括指令指针116以指定正在被此线程执行的当前指令。当线程2在临界段内时,此指令指针引用临界段内的存储器。线程3118是一个写者,正等待
2个之前的读者(即,线程I和2)离开后进入临界段。线程3包括包含队列节点3122的栈120,以及指令指针124。线程4126是一个读者,它正在其栈130上构建队列节点4128,准备将该节点加入到队列中。当线程4将队列节点4128加入队列后,线程4会等待直到之前 的写者(线程3)发信号通知它已经离开临界段。一旦队列节点4128被加入队列中,读者写者互斥体108会变化以指向队列节点4128为队列的新尾部。线程4也包括指令指针130。图2是根据本发明一个实施例的使用具有读者写者互斥体的队列的流程图。在框200,期望访问临界段的一线程在该线程的栈上创建队列节点。这是图I所示例子中线程4126所处的步骤。在框202,该线程将新创建的队列节点加入到队列的尾部。在框204,该线程通过绕其队列节点旋转来等待进入临界段。这是图I所示例子中线程3118所处的步骤。在框206,当线程获得锁定时,该线程被允许进入临界段。这是图I所示例子中线程1100和线程2102所处的步骤。在框208,线程退出临界段。在框210,线程从队列中移除该队列节点。最后,在框212,线程从线程的栈中删除该队列节点。图3是根据本发明一个实施例的队列节点300的详细结构图。一个队列节点包括一个表示要获得互斥体并访问临界段的请求的数据结构,并且包括至少5个字段。NodeState (节点状态)字段302规定关于或对于拥有线程的信息。根据本发明的一个实施例,此值可为Writer (写者)、Reader (读者)UnblockNext (解除阻止下一个)或ActiveReader(活动读者)。Writer状态指示线程计划写入数据至临界段中。Reader状态指示线程计划读取临界段中的数据。根据本发明的一个实施例,UnblockNext状态让后续线程发信号通知它只是部分地链接了其自身的队列节点,因此当前线程应等待直到后续队列节点完全链接。ActiveReader状态指示该线程正在临界段中且活动地读取数据。Next (下一个)字段304是队列中的下一队列节点的指针(指向队列尾部)。Next字段指向储存在另一线程的栈内的队列节点。WaitState (等待状态)字段306规定线程的等待状态(线程是等待还是继续进行)。根据本发明的一个实施例,其类型可以是Spin (旋转)、Going (行进)或Busy(忙碌)。Spin状态指示线程正在等待。Going状态指示线程可访问临界段。根据本发明的实施例,Busy状态指示队列节点还不能被删除。这避免在所有线程完成访问队列节点之前太早的破坏它。Previous (前一,Prev)字段308是队列中前一队列节点的指针(指向队列首部)。根据本发明的实施例,Flag (标志)字段309可包括Previous字段中的一个否则不会被使用的位(例如,一低数位),作为协调从队列中移除队列节点的标志位。EL字段310包括一简单旋转互斥体,用于辅助从队列中间删除读者的原子性。表I显示ReaderWriterMutex (读者写者互斥体)和QueueNode (队列节点)的内部结构。为了便于与现有技术比较,加下划线的文字指示本发明相对于Krieger等人的参考文献中披露的代码增加的代码,加删除线的文字表示本发明相对于Krieger等人的参考文献中披露的代码删除的代码。文体上和明显的修改未被标出。表I
1enum NodeState—t f
2WRITER. READER, UWBLOCKMBXT, ACT1VERBADBR 3};
4ettnni WaitState—t {
5SPIN, GOIMG5 BUSY
};
7struct QueueNode {
8QueueNode* Prev;
9QueueNode* Next;
10NodeStateJ NodeState;
11WattStateJ WaitStafe;
12SpinLockEL;
13};
14struct EeaderWriterM utex {
15QueueNode* Qtail;'
16};图4是根据本发明一个实施例的详细示出样本队列节点值的图I所示示例性队列的示意图。读者写者互斥体结构108包括指向队列尾部(Qtail)的指针。队列节点1106具有值为ActiveReader的NodeState字段,且队列节点I的WaitState字段被设置为Going,因为创建队列节点I的线程已访问临界段并且是读者。Next字段指向队列中的下一队列节点(即,队列节点2114)。Prev字段指向空(null),因为此队列节点是队列首部。队列节点I的EL字段是Unlocked(开锁)。类似地,队列节点214具有值为ActiveReader的NodeState字段,且队列节点2的WaitState字段被设置为Going,因为创建队列节点2的线程已访问临界段并且是读者。Next字段指向队列中的下一队列节点(如队列节点3122)。Prev字段指向队列节点I因为在队列中该队列节点在队列节点2的前面。队列节点2的EL字段是Unlocked。对于队列节点3122, NodeState字段的值是Writer。Next字段指向null因为队列节点3当前是队列的尾部。WaitState字段被设置为Spin,因为队列节点3正在等待轮到其访问临界段。Prev字段指向队列中的前一队列节点(如队列节点2114)。队列节点3的EL字段是Unlocked。
对于队列节点4128, NodeState字段的值是Reader。Next字段和Prev字段指向null,因为此队列节点是新创建的,还未链接到队列。WaitState字段被设置为Spin,因为队列节点4正在等待轮到其访问临界段。Flag被设置为零。队列节点4的EL字段是Unlocked。表II显示处理线程中的用于读者的典型调用顺序。相似的程序调用也可用于写者。在本发明的实施例中,调用中的线程可在其栈上分配其队列节点。Krieger等人和Mellor-Crummey的引用文献中所披露的技术对读者不允许如此。表II
权利要求
1.一种实现公平可缩放的读者写者互斥以便对临界段进行访问的计算机实现方法,所述方法包括 为在处理器上执行的多个处理线程的第一线程创建第一队列节点,所述第一队列节点表示所述第一线程访问所述临界段的请求; 将队列中的至少一个指针设置为指向所述第一队列节点,所述队列表示期望访问所述临界段的至少一个线程列表,所述第一队列节点被添加至所述队列的尾部; 等待直到条件符合,所述条件包括所述第一队列节点由所述队列上的至少一个先前队列节点指示所述第一队列节点没有在前的写入请求; 响应于条件符合,允许所述第一线程进入所述临界段;以及 使所述第一线程释放旋转锁定,所述旋转锁定由所述多个处理线程的第二线程所获得。
2.如权利要求I所述的方法,其特征在于,作为读者的线程绝不阻止作为读者的另一线程。
3.如权利要求I所述的方法,其特征在于,还包括 当第二队列节点已被所述多个处理线程的第三线程删除时,阻止所述第一线程引用所述第二队列节点的尝试。
4.如权利要求I所述的方法,其特征在于,当一读者线程将一队列节点部分地链接入所述队列之后且同时它的前一线程正试图获得所述临界段的读者写者互斥体上的锁定时,所述读者线程使得所述前一线程等待直到所述读者线程完成将所述队列节点链接入所述队列。
5.如权利要求I所述的方法,其特征在于,每一队列节点包括多个等待状态之一,且所述多个等待状态之一包含Busy状态,所述Busy状态指示一队列节点还不能被删除。
6.如权利要求I所述的方法,其特征在于,每一队列节点包括多个节点状态之一,且线程之间的节点状态的通知是由原子运算来完成的。
7.如权利要求6所述的方法,其特征在于,所述节点状态之一包括UnblockNext状态,所述UnblockNext状态允许后续线程发信号通知所述后续线程还只是部分地链接了所述后续线程的队列节点。
8.如权利要求I所述的方法,其特征在于,将队列中的至少一个指针设置为指向所述第一队列节点包括使用CompareAndSwap来将所述队列的尾部从空指针切换为指向所述第一队列节点。
9.如权利要求I所述的方法,其特征在于,所述队列上的每一队列节点是读者节点和写者节点中的一个。
10.一种用于实现公平可缩放的读者写者互斥体以便对临界段进行访问的装置,所述装置包括 用于为在处理器上执行的多个处理线程的第一线程创建第一队列节点的装置,所述第一队列节点表示由所述第一线程访问所述临界段的请求; 用于将队列中的至少一个指针设置为指向所述第一队列节点的装置,所述队列表示期望访问所述临界段的至少一个线程列表,所述第一队列节点被添加至所述队列的尾部; 用于等待直到条件符合的装置,所述条件包括所述第一队列节点由所述队列上的至少一个先前队列节点指示所述第一队列节点没有在前的写入请求; 用于响应于条件符合,允许所述第一线程进入所述临界段的装置;以及 用于使所述第一线程释放旋转锁定的装置,所述旋转锁定由所述多个处理线程的第二线程所获得。
11.如权利要求10所述的装置,其特征在于,作为读者的线程绝不阻止作为读者的另一线程。
12.如权利要求10所述的装置,其特征在于,还包括 用于在第二队列节点已被所述多个处理线程的第三线程删除时阻止所述第一线程引用所述第二队列节点的尝试的装置。
13.如权利要求10所述的装置,其特征在于,当一读者线程将一队列节点部分地链接入所述队列之后且同时它的前一线程正试图获得所述临界段的读者写者互斥体上的锁定时,所述读者线程使得所述前一线程等待直到所述读者线程完成将所述队列节点连接入所述队列。
14.如权利要求10所述的装置,其特征在于,每一队列节点包括多个等待状态之一,且所述多个等待状态之一包含Busy状态,所述Busy状态指示一队列节点还不能被删除。
15.如权利要求10所述的装置,其特征在于,每一队列节点包括多个节点状态之一,且线程之间的节点状态的通知是由原子运算来完成的。
16.如权利要求15所述的装置,其特征在于,所述节点状态之一包括UnblockNext状态,所述UnblockNext状态允许后续线程发信号通知所述后续线程还只是部分地链接了所述后续线程的队列节点。
17.如权利要求10所述的装置,其特征在于,将队列中的至少一个指针设置为指向所述第一队列节点包括使用CompareAndSwap来将所述队列的尾部从空指针切换为指向所述第一队列节点。
18.如权利要求10所述的装置,其特征在于,所述队列上的每一队列节点是读者节点和写者节点中的一个。
全文摘要
实现公平可缩放的读者写者互斥以便由处理系统中多个处理线程访问临界段,通过如下完成为第一线程在第一线程的栈上创建第一队列节点,该队列节点表示第一线程对访问临界段的请求;将第一节点加入由用于所述临界段的单字读者写者互斥体指向的队列,该队列表示期望访问临界段的线程列表,该队列中的每一队列节点位于所述多个处理线程中的一线程的栈上;等待直到由队列中的先前队列节点指示该第一队列节点没有在前的写入请求;由第一线程进入所述临界段;由第一线程退出所述临界段;以及从该队列中清除第一队列节点。
文档编号G06F9/52GK102880518SQ20121031999
公开日2013年1月16日 申请日期2006年8月3日 优先权日2005年8月30日
发明者A·库卡诺夫, A·罗宾森 申请人:英特尔公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1