CN115904744A - 线程持锁方法、装置、电子设备及计算机可读介质 - Google Patents
线程持锁方法、装置、电子设备及计算机可读介质 Download PDFInfo
- Publication number
- CN115904744A CN115904744A CN202211699161.5A CN202211699161A CN115904744A CN 115904744 A CN115904744 A CN 115904744A CN 202211699161 A CN202211699161 A CN 202211699161A CN 115904744 A CN115904744 A CN 115904744A
- Authority
- CN
- China
- Prior art keywords
- thread
- lock
- queue
- threads
- type
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Classifications
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本申请公开了一种线程持锁方法、装置、电子设备及计算机可读介质,涉及计算机技术领域,方法包括:确定当前待持锁的每个待选线程和待持锁的类型;基于待持锁的类型从每个待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型;基于各个待选线程的目标信息,从多个待选线程中确定至少一个持锁优先级满足预设条件的待选线程作为目标线程;控制所述目标线程进入目标线程的临界区持锁。也就是说,所确定的可以持锁的线程的参考依据可以包括等锁时长、临界区长度、持锁绝限时间和线程类型等因素,参考的因素较丰富,能够较好地从多个待持锁的线程中确定可持锁的线程。
Description
技术领域
本申请涉及计算机技术领域,更具体地,涉及一种线程持锁方法、装置、电子设备及计算机可读介质。
背景技术
随着移动互联网的发展,手机已经成了人们随身必备工具之一。除了基本的功能,手机的流畅性和续航也是核心需求。目前手机平台上的移动APP的功能越来越复杂,产生越来越多的高并发的场景,为了应对这些并发场景,安卓手机平台的l inux内核、虚拟机、c库、JAVA库中提供了很多的锁机制来保证在这些并发场景中的逻辑正确性。然而,目前的锁机制中确定持锁的线程的方式表现不佳。
发明内容
本申请提出了一种线程持锁方法、装置、电子设备及计算机可读介质,以改善上述缺陷。
第一方面,本申请实施例提供了一种线程持锁方法,其特征在于,包括:确定当前待持锁的每个待选线程和所述待持锁的类型;基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型;基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;控制所述目标线程进入目标线程的临界区持锁。
第二方面,本申请实施例还提供了一种线程持锁装置,包括:第一确定单元、第二确定单元、第三确定单元和持锁单元。第一确定单元,用于确定当前待持锁的每个待选线程和所述待持锁的类型。第二确定单元,用于基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型。第三确定单元,用于基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。持锁单元,用于控制所述目标线程进入目标线程的临界区持锁。
第三方面,本申请实施例还提供了一种电子设备,包括:一个或多个处理器;存储器;一个或多个应用程序,其中所述一个或多个应用程序被存储在所述存储器中并被配置为由所述一个或多个处理器执行,所述一个或多个应用程序配置用于执行上述方法。
第四方面,本申请实施例还提供了一种计算机可读介质,所述可读存储介质存储有处理器可执行的程序代码,所述程序代码被所述处理器执行时使所述处理器执行上述方法。
本申请提供的线程持锁方法、装置、电子设备及计算机可读介质,对于当前待持锁的待选线程,确定该待选线程请求持的锁的类型,然后,基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型,基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;控制所述目标线程进入目标线程的临界区持锁。也就是说,所确定的可以持锁的线程的参考依据可以包括等锁时长、临界区长度、持锁绝限时间和线程类型等因素,参考的因素较丰富,能够较好地从多个待持锁的线程中确定可持锁的线程。
本申请实施例的其他特征和优点将在随后的说明书阐述,并且,部分地从说明书中变得显而易见,或者通过实施本申请实施例而了解。本申请实施例的目的和其他优点可通过在所写的说明书、权利要求书、以及附图中所特别指出的结构来实现和获得。
附图说明
为了更清楚地说明本申请实施例中的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1示出了本申请提供的自旋锁的结构示意图;
图2示出了本申请提供的互斥锁的结构示意图;
图3示出了本申请提供的读写锁的结构示意图;
图4示出了本申请一实施例提供的线程持锁方法的方法流程图;
图5示出了本申请另一实施例提供的线程持锁方法的方法流程图;
图6示出了本申请一实施例提供的线程入队的示意图;
图7示出了本申请一实施例提供的线程出队的示意图;
图8示出了本申请又一实施例提供的线程持锁方法的方法流程图;
图9示出了本申请一实施例提供的主自旋队列和副自旋队列的示意图;
图10示出了本申请又一实施例提供的线程持锁方法的方法流程图;
图11示出了本申请一实施例提供的读写锁的等待队列的示意图;
图12示出了本申请另一实施例提供的读写锁的等待队列的示意图;
图13示出了本申请再一实施例提供的线程持锁方法的方法流程图;
图14示出了本申请一实施例提供的自旋队列的持锁方式的示意图;
图15示出了本申请再另一实施例提供的线程持锁方法的方法流程图;
图16示出了本申请再又一实施例提供的线程持锁方法的方法流程图;
图17示出了本申请再再另一实施例提供的线程持锁方法的方法流程图;
图18示出了本申请一实施例提供的线程持锁装置的模块框图;
图19示出了本申请一实施例提供的电子设备的结构示意图;
图20示出了本申请一实施例提供的计算机可读介质的示意图。
具体实施方式
为了使本技术领域的人员更好地理解本申请方案,下面将结合本申请实施例中附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。通常在此处附图中描述和示出的本申请实施例的组件可以以各种不同的配置来布置和设计。因此,以下对在附图中提供的本申请的实施例的详细描述并非旨在限制要求保护的本申请的范围,而是仅仅表示本申请的选定实施例。基于本申请的实施例,本领域技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本申请保护的范围。
应注意到:相似的标号和字母在下面的附图中表示类似项,因此,一旦某一项在一个附图中被定义,则在随后的附图中不需要对其进行进一步定义和解释。同时,在本申请的描述中,术语“第一”、“第二”等仅用于区分描述,而不能理解为指示或暗示相对重要性。
随着移动互联网的发展,手机已经成了人们随身必备工具之一。除了基本的功能,手机的流畅性和续航也是核心需求。目前手机平台上的移动APP的功能越来越复杂,产生越来越多的高并发的场景,为了应对这些并发场景,安卓手机平台的l inux内核、虚拟机、c库、JAVA库中提供了很多的锁机制来保证在这些并发场景中的逻辑正确性。
当前手机***中的锁机制主要包括spin lock自旋锁、mutex互斥锁和rwsem读写锁,下面对的spin lock自旋锁、mutex互斥锁和rwsem读写锁工作原理及其存在的问题做简要阐述。
如图1所示,图1示出了自旋锁(spin lock)的示意图。目前,操作***内核中的自旋锁是排队自旋锁,自旋锁通过包括一个全局锁和多个cpu锁组成。全局锁有两个状态:空闲状态和持锁状态,即第一参数un locked(0)表示空闲,第二参数locked(1)表示已经被持有。当线程试图进入临界区持锁的时候会首先检查全局锁的状态,如果等于0,该线程会持锁成功,将全局锁状态修改为1,同时该线程就成为该自旋锁的持锁线程(owner task)。当第二个线程试图持锁进入临界区的时候,由于锁已经有了owner task,因此该线程只能在全局锁上自旋,即进入自旋队列,等待owner task释放锁。当后续持续有线程试图进入临界区的时候,这些线程也同样会进入自旋状态,只不过是自旋在自己所在CPU的per cpu锁上。所有自旋的任务会按照FI FO的顺序形成自旋队列。其中,线程的临界区为线程访问并使用共享资源的代码,线程在访问共享资源的时候,需要持锁然后运行该临界区的代码,以避免其他的线程访问该共享资源。
***会为每个cpu分配一个自旋锁(即per cpu锁),在已经存在全局锁自旋任务的时候,后续的自旋线程都是自旋在自己的per cpu锁上,从而解决了缓存颠簸的问题。percpu锁有点类似同步机制中的cond it ion var ib le,有两个状态:0表示没有资格去轮询全局锁,1表示获取去轮询全局锁的机会。在owner task离开临界区的时候,自旋在全局锁的任务会获取spin lock,同时将队列中的下一个任务对应的per cpu锁状态修改为1,使其获取轮询全局锁的机会。按照这样的逻辑,队列中的任务会按照等锁的时间顺序依次获取自旋锁,从而保证了锁的公平性。
如图2所示,图2示出了互斥锁(Mutex)的示意图。互斥锁是一种睡眠锁,与自旋锁一样,睡眠锁也有一个变量来表示当前的状态,当前锁的状态是un locked(0),那么线程可以进入临界区,同时将锁设置为locked(1)状态。一旦锁进入locked状态之后,其他的线程无法获准进入临界区。当线程无法进入临界区的时候,当前线程有两种选择:自旋等待或者挂入等待队列。如果当前线程自旋等待,那么cpu会持续占用当前CPU资源。如果当前线程挂入等待队列,这时候***会进行线程切换,调度其他线程执行。采用自旋等待是因为本身线程切换就会有一定的开销和副作用,如果持锁线程正在CPU上运行,那么大概率会在一个较短的时间内执行完临界区的代码,释放掉锁。而当前线程自旋等待一会就可以获得锁,进入临界区。因此为了和spin lock的自旋区分开,互斥锁的自旋也被叫做乐观自旋。
如图3所示,图3示出了读写锁的示意图。Mutex互斥锁严格限制只有一个线程可以进入临界区,但是有些***场景可以把临界区区分为读和写,即有些临界区是仅仅读取共享资源,有些临界区不仅仅读取共享资源,还会更新共享资源。这时候,为了增加吞吐量,***实现了可以允许多个读(reader)线程进入临界区的读写锁。对于写(wr iter)线程而言,只能有一个wr iter线程在临界区内执行,而对于读线程,临界区的读线程可以有多个。
对于读写锁,进入临界区的规则如下:如果读写锁是空锁状态,即未有任何线程进入临界区,则任何读线程或者写线程都可以进入临界区,但是,读线程和写线程只能是其中之一进入临界区。如果临界区内有一个读线程,此时新来的读线程可以进入临界区,但是写线程不可以进入临界区。如果临界区内已经有了写线程,此情况下,无论是读线程还是写线程都不可以进入临界区。如果临界区内有若干个读线程,且有至少一个写线程进入了阻塞状态(即在自旋队列或等待队列中),此情况下,无论是读线程还是写线程都不可以进入临界区。读写锁和互斥锁一样,当reader或者写线程无法获得锁进入临界区的时候,可以选择乐观自旋或者挂入等待队列,进入阻塞状态。
然而,发明人在研究中发现,由于l inux内核本身并非是一个专门为移动平台设计的操作***内核,其锁机制的设计逻辑是基于公平的思路,因此l inux中的锁机制在手机平台上表现不佳。同样的,在虚拟机、c库、Java库中的锁机制无一例外,都采用了公平的思路,也都存在锁机制表现不佳的缺陷。
如图4所示,图4示出了本申请实施例提供的一种线程持锁方法,该方法包括:S401至S404。
S401:确定当前待持锁的每个待选线程和所述待持锁的类型。
其中,该待持锁为待持锁线程请求持有的锁,基于待持锁线程主动请求持锁的持锁请求可以确定待持锁线程请求持锁的类型,还可以是操作***为该待持锁线程分配一个待持锁,从而能够确定待持锁的类型,则该待持锁的类型为上述的互斥锁、自旋锁和读写锁。需要说明的是,该当前待持锁的多个线程请求持有的锁的类型为同一个,当操作***内存在请求持有多个锁的待持锁线程的时候,针对每个类型的锁对应的待持锁线程为该类型的锁对应的待选线程。作为一种实施方式,该当前待持锁的每个待选线程可以是请求持锁失败的线程,也可以是未请求持锁而是直接进入持锁等待队列的线程。
需要说明的是,执行确定当前待持锁的每个待选线程和所述锁的类型的步骤,可以是在当前已经存在处于临界区的持锁线程的情况下执行的,即在确定当前已经存在处于临界区的持锁线程的情况下,确定当前待持锁的每个待选线程和所述锁的类型。当然,也可以是在检测到任意线程持锁失败的情况下,确定当前待持锁的每个待选线程和所述锁的类型,即确定请求持有该锁的所有线程,因为,虽然在确定当前的持锁失败的线程之前,已经确定该当前持锁线程之前的待持锁线程,但是,由于新出现的持锁线程可能会导致当前所有等待持锁的线程的持锁优先级发生改变,所以需要基于所有的待持锁的线程重新确定各个线程的持锁优先级。
S402:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型。
可以理解的是,该等锁时长是指待持锁线程从本次等待持锁的时刻开始至当前时刻的时间长度,等锁时长反应了该线程当前持续处于等待持锁状态的时间长度。临界区是指进程中访问临界资源的一段需要互斥执行的代码。也就是说,在线程持锁的状态下,线程会进入临界区,并且在临界区通过持锁的方式访问临界资源(即共享资源)。临界区长度与临界区的代码的指令条数有关,也就是说,临界区的代码的指令条数越多,临界区长度越长,临界区的代码的指令条数越少,临界区的长度越短,即临界区长度与临界区的代码指令条数正相关,另外,除了临界区的代码的指令条数之外,临界区长度还与线程运行临界区代码的时候的运行时间相关,即运行时间越长,临界区长度越长,运行时间越短,临界区的长度越短,而线程运行该临界区代码的运行时长与该线程所在的处理器有关,即与该线程所在的处理器的运行参数有关,如果该处理器的运行速度比较快,则该处理器的运行时长会比较短,反之,会更长,因此,于本申请实施例中,可以基于所述临界区的代码指令条数以及该运行该临界区对应的待选线程的处理器的运行参数而确定。示例性地,可以是临界区的代码指令条数作为第一参考值,运行该临界区对应的待选线程的处理器的运行参数作为第二参考值,将第一参考值和第二参考值分别计算得到第一长度和第二长度,再将第一长度和第二长度通过加权求和的方式得到临界区长度。其中,第二长度可以是一个调整系数,是一种经验值,示例性地,该处理器的运行参数(例如,负载等)能够反应处理器的数据运算能力,相同长度的代码在不同运算能力的处理器上运行,其运行的时间也是不同的,而临界区长度反应了该临界区的代码的运行耗时,所以,该耗时不仅与代码的长度有关,而且与运行该代码的处理器的运行参数有关。当然,在一些实施例中,该临界区的长度也可以直接基于第一长度得到,在此不做限定。
另外,通常,延迟敏感度可以表征该线程的等待持锁的时长对该线程的用户体验度的影响。运行在电子设备内的各个应用程序的线程可以分为Ux线程和Non-Ux线程,其中,Ux线程通常是参与到了当前界面的绘制、渲染或者声音的播放,这类任务属于延迟敏感型任务,Non-Ux线程通常是和用户体验无关,例如一些后台的用于统计某些数据的线程。上层软件根据当前的应用场景对不同的任务(Ux线程和Non-Ux线程)设置不同的持锁时延需求,通常,Ux线程的持锁时延要小于Non-Ux线程。并且,同样都是Ux线程,音频线程的持锁时延要求更严格,因为用户对声音的敏感度要高于视觉。以及,同样是界面流畅度相关的Ux线程,动画线程要比启动线程的持锁时延要求更高,因为用户对动画丢帧的容忍度更低。
因此,可以对在电子设备的操作***上运行的所有线程查找与用户感知相关的线程,作为Ux线程,其他的线程作为Non-Ux线程,并且为不同的Ux线程和Non-Ux线程设置不同的延时敏感度,需要说明的是,该延时敏感度可以是自定义一个数值,该数值越大表示延时敏感度越高,而考虑到该延时敏感度与等待时长是相关的。
需要说明的是,该持锁绝限时间(也称为dead l ine)与前述的延时敏感度有关,示例性地,待持锁线程的持锁绝限时间表征的是该线程需要完成持锁操作的绝限时间,例如,持锁绝限时间为13:04,可以看出该线程需要最晚在13:04完成持锁操作。则持锁绝限时间为等锁起始时刻与持锁时延阈值之和,其中,等锁起始时刻为线程的等锁开始的时间点容易确认,可以通过确定线程持锁请求被卡住的时刻作为该线程的等锁开始的时间点即等锁起始时刻,持锁时延阈值表征的是从开始等待持锁到完成持锁之间的所允许的最大时长,示例性地,该持锁时延阈值基于待选线程与用户感知的关联程度而确定,待选线程与用户感知的关联程度与该线程的持锁时延阈值负相关,也就是说,待选线程与用户感知的关联程度可以是该线程的延时敏感度,即该线程的延时敏感度越高,该线程与用户感知的关联程度越高,该线程对应的持锁时延阈值越小。
其中,前述提及的两个术语在此解释。与用户感知相关的线程,也可以认为是与用户交互相关的线程,具体地,应用程序(app l icat ion,APP)通常是多个程序的集合,每个程序对应一个进程,而每个进程下对应至少一个线程,也就是说,进程可以是单线程的,也可以是多线程的。可以理解的是,一个进程即是一个实例,也就是说,一个进程可以对应应用程序的一个功能,例如,应用程序的视频播放功能可以是应用程序的一个进程,通常,应用程序运行时的进程为主进程,应用程序下的各个功能可以是该主进程的子进程。
与用户交互相关的线程,可以是指该线程用于获取用户操作应用程序时产生的操作数据,还可以是该线程用于输出与用户感知相关的数据。针对前者,用户操作可以是用户在应用程序的某个界面上的滑动操作、点击操作等,则应用程序包括能够检测滑动操作和点击操作的线程,则该线程属于与用户交互相关的线程。针对后者,输出与用户感知相关的数据可以是播放音频数据和视频数据等能够被用户听觉或视觉感知的数据。
另外,该与用户交互相关的线程还可以是与应用程序的各个显示界面相关的线程,即服务于显示界面的线程。例如,以应用程序的某个视频播放界面为例,视频播放界面上设置有视频播放控件,则用于服务于视频播放控件以使视频播放控件能够播放视频的线程就属于与用户交互相关的目标线程。
则前述的用户操作相关的数据、能够被用户感知的数据或者应用程序所显示的界面,对于用户来说,都属于与用户交互相关的数据,则能够产生或者获取这些数据的线程相比一些在后台运行而与用户不存在交互的线程相比,如果产生卡顿,那用户能够强烈感知到,所以,本申请实施例从应用程序的所有待选线程中查找与用户交互相关的目标线程,并且设置能够满足该目标线程的使用需求的休眠模式,以便能够确保应用程序中那些能够被用户感知明显的功能模块的运行不会卡顿。示例性地,如果当前场景是前台应用的界面渲染场景,则目标线程为该应用的界面渲染相关的线程,例如,可以是该应用的主线程,如果当前场景是音频播放场景,则该目标线程为音频播放线程,也就是说,当前场景是在视觉上和听觉上能够让感受到变化的场景,且该场景的目标线程是实现该场景的功能的核心线程,也可以称之为关键线程。
另外,前述提及的线程被卡住就是该线程被挂入持锁等待队列,不能在CPU上继续执行了。线程一旦挂入运行队列,那么CPU就会按照调度算法给这个线程一定的CPU时间片,来运行该线程。例如,当一个线程未成功持有互斥锁(有其他线程已经持有该互斥锁),那么该线程就会进入阻塞状态(挂入等待队列),无法继续在CPU上执行。
再者,线程类型是指线程被划分的类别,例如,基于线程与用户感知的关联度,可以将线程划分为前述的Ux线程和Non-Ux线程,再例如,基于线程所执行的操作是读操作还是写操作,可以将线程类型划分为读类型和写类型,则读类型的线程为读线程reader,写类型的线程为写线程wr iter。
由于不同的锁类型下,影响线程持有该锁的延时的因素不同,所以,不同锁类型锁需要考虑的属性信息也不同,因此,基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,则后续实施例将针对各个不同类型的锁所使用的属性信息以及如何使用属性信息确定持锁优先级作进一步阐述。
S403:基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。
示例性地,基于每个所述待选线程的目标信息,确定每个待选线程的持锁优先级,然后,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。其中,持锁优先级用于确定该多个待选线程中的每个线程的持锁的先后顺序,持锁优先级最高的线程,最先持锁,持锁优先级最低的线程,最后持锁。于本申请实施例中,如果从待选线程中确定一个待选线程去持锁,则该持锁优先级满足预设条件可以是指持锁优先级最高,如果从待选线程中确定多个待选线程去持锁,则该持锁优先级满足预设条件可以是指将多个并列最高的持锁优先级的待选线程作为目标线程。
S404:控制所述目标线程进入目标线程的临界区持锁。
具体地,可以是在当前的持锁线程释放锁的情况下,该目标线程可以抢占该锁,也就是说,将所述当前线程持有的锁释放,并触发目标线程抢占所述当前线程占用的CPU资源以及进入该线程的临界区持锁,运行该线程的临界区内的代码,基于抢占的所述CPU资源执行所述目标线程。对于一些实施方式,可以在目标线程在抢占CPU资源后,直接基于抢占的CPU资源,执行该目标线程,从而使目标线程可以持有该锁,进而再基于抢占的CPU资源执行目标线程。
因此,本申请实施例中,对于当前待持锁的待选线程,确定该待选线程请求持的锁的类型,然后,基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型,基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;控制所述目标线程进入目标线程的临界区持锁。也就是说,所确定的可以持锁的线程的参考依据可以包括等锁时长、临界区长度、持锁绝限时间和线程类型等因素,参考的因素较丰富,能够较好地从多个待持锁的线程中确定可持锁的线程。
下面将针对不同类型的锁,分别阐述各个锁的持锁优化方案。
如图5所示,图5示出了本申请实施例提供的一种线程持锁方法,该方法实施例中,锁的类型为第一互斥锁,多个所述待选线程位于所述互斥锁对应的等待队列中,需要说明的是,本事实例中,该互斥锁命名为第一互斥锁,后续涉及到第二互斥锁,因为两个互斥锁对应的队列以及持锁逻辑不同,因此,通过不同的命名区分。该方法包括:
S501:确定当前待持锁的每个待选线程和所述待持锁的类型。
S502:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息。
于本申请实施例中,该锁的类型为互斥锁,则该目标信息可以包括等锁时长、持锁绝限时间(dead l ine)和临界区长度,也就是说,通过等锁时长确定一个目标线程,避免出现饿死的情况,即避免出现一个线程等待很久都没有成功持锁。
示例性地,可以将第一互斥锁的等待队列划分为第一队列、第二队列和第三队列,其中,前述的各个待选线程均位于第一队列和第三队列中,第二队列用于存放该各个待选线程中的与用户相关的线程即Ux线程,第一队列从队首至队尾的各个线程的等锁时长依次降低,第二队列从队首至队尾的各个线程的持锁绝限时间依次增大,第三队列从队首至队尾的各个线程的临界区长度依次增大。其中,第一队列可以理解为互斥锁的原始等待队列,即互斥锁等待队列的排队算法都是FI FO的,即先到先得,越早等待在第一队列、第二队列和第三队列的线程优先进入临界区。因此,在将线程挂入第一队列的时候就是简单的挂入队列尾部,而唤醒的时候,总是唤醒队列头部的等待任务。
于本申请实施例中,可以对原始等待队列改进,得到改进后的队列,即除了包括原始等待队列(即第一队列),还包括第二队列和第三队列。示例性地,对等待队列改进的参考策略是:1、当前挂入等待队列的任务的延迟需求。上层软件根据当前的应用场景对不同的任务设置不同的持锁时延需求,Ux线程的持锁时延要小于Non-Ux线程的持锁时延。也就是说,Ux线程的持锁时延阈值小于Non-Ux线程的持锁时延阈值。同样都是Ux线程,音频线程的持锁时延要求更严格,音频线程的持锁时延阈值更低,因为用户对声音的敏感度要高于视觉。同样是界面流畅度相关的Ux线程,动画线程要比启动线程的持锁时延要求更高,动画线程的持锁时延阈值更低,因为用户对动画丢帧的容忍度更低。2、临界区的执行时间。可以为每一把锁的持锁线程增加一个临界区长度的参数,这个临界区长度可以根据临界区的代码指令条数以及当前执行的CPU微架构和运行频率进行调整。在进行排队的时候,根据临界区长度来进行排序,让临界区执行时间短的任务排在队列的前面,而临界区执行时间长的任务排在队列的尾部。3、避免饿死现象。上层软件根据当前的应用场景设定一个最大持锁时延,***中任何一个线程的持锁时延一旦大于当前设定的最大持锁时延。那么都要优先唤醒这些线程持锁,不再允许ux线程插队或者短临界区的线程插队。
如图6所示,改进后的等待队列的组织成如下的方式:1、按照等待开始时间点进行排序的第一队列(即原始的FI FO队列)。这个队列中,队首的任务就是最早等待在该锁的任务,也就是等待时间最久的任务。而队尾是最新的等待任务。2、按照持锁绝限时间(dead line)进行排序的第二队列。如前所述,持锁绝限时间为等锁起始时刻与持锁时延阈值之和,由于Ux线程的持锁时延阈值相比Non-Ux更小,故Ux线程会有更大的概率排在队列的首部,并且,如前所述,即使都是Ux线程,有些Ux线程的持锁时延阈值相比其他的Ux线程的持锁时延阈值更小,那么该持锁时延阈值更小的Ux线程在第二队列中也会有较大的概率排在队列靠前的位置。3、按照临界区长度进行排序的第三队列(临界区队列),队列的首部是临界区短的任务。如图6所示,假设线程1持锁失败之后进入等待持锁状态,然后,***第一队列的队尾,然后,获取该线程1的临界区长度,基于该线程1的临界区长度确定该线程1在第三队列中的第一位置并***该第一位置,确定该线程1是否属于Ux任务,如果属于Ux任务,则获取待线程1的持锁绝限时间,基于该线程1的持锁绝限时间确定该线程1在第二队列中的第二位置并***该第二位置,如果不属于Ux任务,则放弃放入第二队列,直接进入阻塞状态,其中,在阻塞状态下,之前本申请的确定目标线程并持锁的操作。
S503:将所述第一队列中的队首的线程作为第一线程。
在第一队列的队首的线程的等锁时长最大,并且该第一队列的各个线程按照从队首至队尾的顺序依次持锁,所以,队首的线程是该第一队列中的持锁优先级最高的线程。所以,在确定是否要从第一队列中查找一个线程持锁的时候,可以选择第一队列中的队首的线程,并命名为第一线程。
S504:判断第一线程的等锁时长是否大于预设时长。
需要说明的是,该预设时长可以根据实际使用需求而设定,该预设时长可以看作是等锁线程的等锁时长的极值,即如果该等锁时长大于该预设时长,则表示线程极有可能会饿死。那么,如果第一线程的等锁时长大于预设时长,则表示第一队列中存在可能饿死的线程,并且该线程是该第一队列中队首的线程。需要说明的是,虽然第一队列中可能存在队首线程以及队首之后的部分线程的等锁时长大于预设时长,则在队首线程的等琐时长大于预设时长的情况下,将队首的线程持锁,在该线程释放锁之后,第一队列的其他的等锁时长大于预设时长的线程继续依次持锁。
S505:将所述第一线程作为目标线程。
若第一线程的等锁时长大于预设时长,则将所述第一线程作为目标线程,即执行S505。
S506:判断所述第二队列是否存在线程。
若第一线程的等锁时长小于或等于预设时长,则执行S506,即判断第二队列是否存在线程,如前所述,第二队列用于存在待持锁线程中与用户相关的线程,所以,如果该待持锁线程中不存在与用户相关的线程,那么第二队列中就不存在线程,如果该待持锁线程中存在与用户相关的线程,那么第二队列中就存在线程,并且该第二队列中的线程按照持锁绝限时间排序,即第二队列从队首至队尾的各个线程的持锁绝限时间依次增大。
S507:将所述第二队列中的队首的线程作为目标线程。
需要说明的是,第二队列与第一队列类似,都是按照队首至队尾的顺序,将队列汇总的线程依次持锁,所以在第二线程存在线程的情况下,将所述第二队列中的队首的线程作为目标线程。
S508:将所述第三队列中的队首的线程作为目标线程。
如果第三队列中不存在线程,也就是说,既没有存在可能饿死的线程,也不存在与用户相关的线程,在此情况下,可以从确定临界区长度最短的线程作为目标线程,而由于第三队列从队首至队尾的各个线程的临界区长度依次增大,所以,将第三队列中的队首的线程作为目标线程。
S509:控制所述目标线程进入所述目标线程的临界区持锁。
如图7所示,在确定出队(即确定目标线程)的时候,1、从第一队列中取出队首的线程,如果该线程的等锁时长超过了***设定的最大持锁时延的门限值(即预设时长),那么唤醒线程将来自第一队列(防止饿死)即第一队列的队首的线程,其他两个队列不考虑。2、如果第一队列的队首的线程未超过预设时长,则从第二队列中取出队首的线程,将其唤醒。只要第二队列中有Ux线程,将不考虑临界区的长度即第三队列。3、如果该第二队列为空即不存在线程,则从临界区队列中取出头部节点,将其唤醒。只有在没有Ux线程和没有饿死的情况下,才考虑按照临界区的长度来确定目标线程。
另外,在一些实施例中,如果确定第一线程的等锁时长不大于预设时长,则可以直接将第二队列中的队首的线程作为目标线程,当然,也可以是基于第二队列中的队首的线程是否为与用户感知相关的线程的判断结果,在第三队列中确定目标线程,对此不做限定。
如图8所示,图8示出了本申请实施例提供的一种线程持锁方法,该方法实施例中,锁的类型为自旋锁,多个所述待选线程位于所述自旋锁对应的自旋队列中,该方法包括:
S801:确定当前待持锁的每个待选线程和所述待持锁的类型。
基于待持锁线程的持锁请求能确定每个待持锁线程请求持锁的类型,即待持锁类型。当然,也可以是预先定义个对应关系,该对应关系内包括每个线程对应的持锁类型,所以,基于该对应关系,也能够确定每个线程的持锁类型,在此不做限定。
S802:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息。
作为一种实施方式,该锁的类型为自旋锁,该目标信息包括等锁时长和临界区长度。
S803:判断是否存在临界区长度小于预设长度的待选线程。
作为一种实施方式,如前所述,不同临界区长度的等待持锁的线程在自旋锁内等待持锁的时候,会引起锁的吞吐量和延迟的问题,因此,本申请实施例基于当前等待持锁的各个待选线程的临界区长度来确定目标线程优先持锁。具体地,可以设定一个预设长度,该预设长度为临界区长度对应的一个阈值,该预设长度可以将临界区划分为长临界区和短临界区,示例性地,将临界区长度小于预设长度的待选线程的临界区作为短临界区,将临界区长度不小于预设长度的待选线程的临界区作为长临界区,并且,在从多个待选线程中确定优先持锁的目标线程的时候,优先从短临界区的各个线程中确定目标线程。其中,于本申请实施例中,该目标线程是当前等待持锁的所有待选线程中持锁优先级最高的线程。
所以,判断是否存在临界区长度小于预设长度的待选线程,如果存在临界区长度小于预设长度的待选线程,也就是说存在短临界区长度的待选线程,则执行S804,否则,执行S805。
S804:从该临界区长度小于预设长度的待选线程中确定等锁时长最大的待选线程作为目标线程。
S805:从多个所述待选线程中确定临界区长度不小于预设长度的线程且等锁时长最大的线程作为目标线程。
S806:控制所述目标线程进入目标线程的临界区持锁。
需要说明的是,在从临界区长度小于预设长度的待选线程或从临界区长度不小于预设长度的线程确定目标线程的时候,依然按照FI FO的策略将最先进入等锁状态的线程即等锁时长最大的线程作为目标线程。
参考图1中的自旋锁,可以发现原生的自旋锁中的自旋队列中,采用FI FO的顺序持锁,如图9所示,为本申请实施例优化后的自旋队列,示例性地,可以将原生的自旋队列划分为主自旋队列和副自旋队列,主自旋队列用于存放各个所述待选线程中临界区长度小于预设长度的线程,且所述主自旋队列从队首至队尾的各个线程的等锁时长依次降低,副自旋队列用于存放各个所述待选线程中临界区长度不小于预设长度的线程,副自旋队列为从队首至队尾的各个线程的等锁时长依次降低。所以,在确定当前存在待持锁的线程的时候,可以直接基于该线程的临界区长度,将该线程放入主自旋队列或副自旋队列,再需要从等待持锁的线程中确定目标线程去持锁的时候,再从主自旋队列或副自旋队列确定目标线程。
示例性地,该S803的实施方式可以是确定该主自旋队列是否存在线程,如果该主自旋队列存在线程,则可以确定当前存在临界区长度小于预设长度的线程,则执行S804,即将所述主自旋队列的队首的线程作为所述目标线程。如果该主自旋队列中不存在线程,则可以确定不存在临界区长度小于预设长度的线程,那么,执行S805,即将所述副自旋队列的队首的线程作为所述目标线程。
也就是说,对于长临界区的线程,可以将其挂入副自旋队列,对于短临界区的线程,可以将其挂入主自旋队列。主自旋队列有优先获取全局锁的权利,只有当主队列为空的时候,副自旋队列才能准许持锁进入临界区。并且,主副队列各自仍然按照FI FO的原则进行排队持锁。
如图10所示,图10示出了本申请实施例提供的一种线程持锁方法,该方法实施例中,锁的类型为第一读写锁,多个所述待选线程位于所述读写锁对应的等待队列中,该方法包括:S1001至S1005。
S1001:确定当前待持锁的每个待选线程和所述待持锁的类型。
需要说明的是,待持锁的类型的确定方式可以参考前述实施例,在此不再赘述。
S1002:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息。
作为一种实施方式,该待持锁的类型为第一读写锁,该目标信息包括线程类型和等锁时长。
S1003:在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程,作为第三线程。
如图11所示,在图11所示的等待队列中,队首的线程为写线程1(wr iter1线程),各个线程进入临界区的顺序如下:写线程1首先入线程1的临界区持锁(即持该第一读写锁);写线程1释放锁之后,写线程1到写线程2之间的所有读线程进入各个读线程的临界区持锁;当写线程1到写线程2之间的所有读线程离开临界区释放锁后,写线程2进入线程2的临界区持锁;写线程2释放锁之后,写线程2之后的所有读线程进入该各个读线程的临界区持锁。
通过上面的描述可知,读写锁本身的应用场景就是写少读多,因此提升其吞吐量主要是依靠让多个读线程(读线程)同时进入临界区来完成的,因此对于读写锁,可以不考虑根据临界区的长度进行重排,主要考虑Ux和饿死两个因素。因此,对于第一读写锁,我们保持原生的等待队列,不再增加新的等待队列。在没有Ux线程的时候,这个队列仍然保持和原生等待队列一样的排列顺序(即按照FI FO的顺序),当有Ux线程的时候,可以将Ux线程(读线程或者写线程)***到合适的位置。
因此,于本申请实施例中,该请求持锁的待选线程,即第三线程可以是优化的等待队列中的线程,即该线程的持锁优先级已经被优化。
S1004:若所述第三线程与用户感知相关且线程类型是读类型,则将所述第三线程作为目标线程。
S1005:控制所述目标线程进入目标线程的临界区持锁。
需要说明的是,基于前述的图3所示的读写锁的原理,如果在临界区内有若干个读线程,且有至少一个写线程进入了阻塞状态(即在自旋队列或等待队列中),此情况下,无论是读线程还是写线程都不可以进入临界区持锁,但是,这样的情况容易导致与用户感知相关的线程在等待队列中被延迟太久时间持锁,导致用户的使用体检大幅度降低。因此,本申请实施例中,在确定当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程的情况下,如果等待队列中请求持锁的待选线程是一个与用户感知相关的读线程,则可以直接允许该线程持锁,即将该第三线程作为目标线程。需要说明的是,如果第三线程不是与用户感知相关的读线程,则该第三线程继续在等待队列中等待持锁,即按照原生的FIFO逻辑持锁。
因此,于本申请实施例中,当前在临界区的线程为一组读类型的线程,即在当前临界区内的线程类型均为读类型,同时还要满足等待队列中已经有至少一个写类型的线程存在,即所述等待队列中存在写类型的线程。在这样的场景下,当一个读线程再试图持锁的时候,按照原生逻辑会失败,从而进入阻塞状态并***等待队列的尾部。优化后的逻辑是区分读线程是Ux线程还是Non-Ux线程。当是Non-Ux线程的时候,仍然保持阻塞并按FI FO顺序***等待队列。
作为一种实施方式,如果第三线程是Ux线程且线程是读类型,在满足预设***条件的情况下,可以直接进入临界区持锁,即直接作为目标线程。该预设***条件包括:在所述等待队列中不存在等锁时长大于预设时长的线程以及当前临界区内读类型的线程不大于预设最大值的至少一种。
在一些实施例中,为了避免等锁线程出现饿死的情况,则可以在确定第三线程与用户感知相关的情况下,确定在所述等待队列中是否存在等锁时长大于预设时长的线程,如果存在等锁时长大于预设时长的线程,则放弃控制第三线程持锁,而是采用上述的FI FO逻辑持锁,如果不存在等锁时长大于预设时长的线程,则表示当前等锁线程不存在饿死的可能性,从而可以将第三线程作为目标线程,控制所述目标线程进入目标线程的临界区持锁,也就是说,该预设***条件为在所述等待队列中不存在等锁时长大于预设时长的线程。
在另一些实施例中,预设***条件可以是当前临界区内读类型的线程不大于预设最大值,则在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程,若所述第三线程与用户感知相关且线程类型是读类型,则在当前临界区内读类型的线程不大于预设最大值的情况下,将所述第三线程作为目标线程。
于本申请实施例中,该预设***条件为在所述等待队列中不存在等锁时长大于预设时长的线程且当前临界区内读类型的线程不大于预设最大值,所以,若所述第三线程与用户感知相关且线程类型是读类型,则将所述第三线程作为目标线程的实施方式为,若所述第三线程与用户感知相关且线程类型是读类型,则在所述等待队列中不存在等锁时长大于预设时长的线程且当前临界区内读类型的线程不大于预设最大值的情况下,将所述第三线程作为目标线程。
如前所述,第一读写锁对应有等待队列,多个所述待选线程位于所述第一读写锁对应的等待队列,等待队列中的各个线程的持锁方式为,在临界区的持锁线程释放锁之后,等待队列中的队首的线程最先持锁,而本申请实施例为了避免读写锁出现延迟的情况,则在获取到等待持锁的线程的时候,在等待队列中合理确定该线程的位置,基于该位置将该线程***等待队列中,所以,在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程之前,方法还包括待持锁线程的插队操作。具体地,该插队操作包括,在所述等待队列中按照从队首至队尾的第一方向,查找第一个等锁时长小于预设时长的线程,作为第四线程;基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中。
假设,该第一读写锁的等待队列如图12所示,写线程1位于等待队列的队首,读线程31位于队列的队尾,则假设写线程1至读线程31的方向为第一方向,因此,沿着第一方向,读线程31位于写线程1的前方,写线程1位于读线程31的后方,则沿着写线程1至读线程31的方向,确定第一个等锁时长小于预设时长的线程,作为第四线程。需要说明的是,对于所确定的当前等待持锁的待选线程来说,等待队列中的线程为在当前等待持锁的待选线程之前处于等锁状态的线程,等待队列内的各个线程基于从队首至队尾的顺序进入临界区。如图12所示,持锁优先级最高,即最先可以持锁的线程为写线程1。
下面将分不同的情况阐述基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中的实施方式。
第一种情况,若当前待持锁的所述待选线程的线程类型为读类型且是Ux线程,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第一线程组,例如,第四线程为读线程12,则第一线程组为读线程11、读线程12和读线程13。将所述待选线程***所述第一线程组的任意位置,该任意位置包括第一线程组任意两个读线程之前的位置、沿第一方向上第一线程组的第一个读线程之后的相邻位置以及最后一个读线程之前的相邻位置,即该任意位置可以理解为第一线程组相邻的两个写线程之间的任意位置,即假设第四线程为读线程12,则可以将该待选线程***写线程1和写线程2之间的任意位置。而如果当前待持锁的所述待选线程的线程类型为读类型,且所述第四线程的线程类型为写类型,将沿所述第一方向上所述第四线程之后的相邻的所有读类型的线程,作为第二线程组,假设第四线程为写线程2,则第二线程组为读线程11、读线程12和读线程13,将所述待选线程***所述第二线程组的任意位置,即***写线程1和写线程2之间的任意位置。
第二种情况,若当前待持锁的所述待选线程的线程类型为写类型且是Ux线程,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第三线程组;将所述待选线程***所述第三线程组的最靠近所述队首的位置。假设第四线程为读线程12,则与读线程12相邻的所有读类型的线程包括读线程11和读线程13,即第三线程组包括读线程11、读线程12和读线程13,则第三线程组最靠近所述队首的位置为沿第一方向上的第三线程组的第一个读线程的后方的相邻位置处,例如,为读线程11和写线程1之间的位置。若当前待持锁的所述待选线程的线程类型为写类型,且所述第四线程的线程类型为写类型,沿所述第一方向将所述待选线程***所述第四线程的前一个位置且与所述第四线程相邻。例如,第四线程为写线程2,则可以将待选线程***写线程2与读线程21之间的位置处。
因此,通过对等待队列的优化,能够在确定当前的等待持锁的线程为与用户感知相关的线程的时候,合理选择该线程在等待队列内的位置,避免与用户感知相关的线程被延时过久,也避免该线程的***导致等待队列出现饿死的现象。
如图13所示,图13示出了本申请实施例提供的一种线程持锁方法,该方法实施例中,锁的类型为第二互斥锁,所述第二互斥锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,本申请实施例用于在等待队列中确定哪些线程可以进入自旋队列进行乐观自旋,具体地,该方法包括:S1301至S1306。
S1301:确定当前待持锁的每个待选线程和所述待持锁的类型。
其中,确定待持锁的类型的方式可以参考前述实施例,在此不再赘述。
S1302:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息。
于本申请实施例中,锁的类型为第二互斥锁,目标信息包括线程类型和等锁时长。与前述第一互斥锁不同的是,该第二互斥锁对应有乐观自旋队列,在该乐观自旋队列中的线程处于乐观状态。如图14所示,目前当无法通过快速路径持锁(例如抢占)的时候,所有线程都会进入乐观自旋状态。所谓的乐观自旋就是通过不断循环(busy loop)的方式不断的去探测下面三个状态:
1、持锁线程(owner task)是否正在CPU上执行,如果没有在CPU上执行(处于offcpu状态,包括被抢占进入runnab le状态,或者由于资源受限进入阻塞状态),那么将停止乐观自旋而进入临界区持锁。
2、当前持锁线程的CPU是否产生了一些异步事件,从而唤醒了更高优先级任务,使得调度器标记了重新调度的标记,如果有重新调度的需求,那么也将停止乐观自旋而进入临界区持锁。
3、当前持锁线程的锁的状态是否变成空闲状态,如果是,停止乐观自旋并持锁进入临界区持锁。
如前所述,当存在乐观自旋队列的时候,会导致等待队列中的线程等待持锁的时长过久,所以,可以基于乐观自旋准入控制、乐观自旋超时和用户感知相关线程优先级较高的策略,优化进入乐观自选队列的线程的选择策略,即下述的S1303和S1304。
S1303:若所述等待队列中不存在等锁时长大于预设时长的线程,基于各个所述待选线程的线程类型,确定所述等待队列中是否存在与用户感知相关的线程。
S1304:若所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中。
如果等待队列中不存在饿死的线程,则确定等待队列中是否存在Ux线程,如果存在Ux线程,则将与用户感知相关的线程加入所述乐观自旋队列中,与用户感知不相关的线程不加入乐观自旋队列中而是在等待队列中等待持锁。如果等待队列中不存在Ux线程,则表示等待队列中的线程都是Non-Ux线程,则可以将这些Non-Ux线程加入乐观自选队列。
另外,还可以考虑当前持锁的持锁线程的临界区长度来确定乐观自旋,由于在乐观自旋队列中的线程处于乐观自旋状态,乐观自旋状态下的线程相比等待队列中的线程所带来的功耗更高,所以,获取当前持锁的线程的临界区长度,如果该临界区长度小于预设长度,则确定等待队列中是否存在等锁时长大于预设时长的线程,若所述等待队列中不存在等锁时长大于预设时长的线程,基于各个所述待选线程的线程类型,确定所述等待队列中是否存在与用户感知相关的线程。因此,本申请实施例中,不再无条件的执行乐观自旋逻辑,仅在线程满足准入条件的情况下才执行乐观自旋,该准入条件包括:1、owner task进入的临界区判定为短临界区的情况下允许乐观自旋;2、当等待队列中有Ux任务时,只有Ux线程可以进行乐观自旋。当等待队列中没有Ux任务时,Non-Ux线程才允许进行乐观自旋;3、当等待队列中有饿死的线程的时候,禁止乐观自旋。
S1305:从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
由于乐观自旋的任务都是在不断的轮询互斥锁的状态,一旦发现锁处于空闲状态就会直接持锁进入临界区,而等待队列中的任务需要有一个唤醒过程,然后采取试图获取锁。所以,在乐观自旋队列中成功抢锁的线程即为目标线程。
S1306:控制所述目标线程进入目标线程的临界区持锁。
需要说明的是,如前所述,由于乐观自旋队列中的线程相比等待队列中的线程更容易持锁,所以,为了避免乐观自旋队列中的线程长期位于乐观自旋队列中,则可以设置一个时间阈值,则该方法还包括:获取乐观自旋队列中每个线程处于乐观自旋队列的时长,记为乐观自旋时长,将乐观自旋时长大于时长阈值的线程移除乐观自旋队列并***等待队列中。也就是说,在线程进入乐观自旋状态的时候启动一个定时器,超时时间可以通过***设置(可以通过特定的负载模型的统计信息来设定该超时时间阈值);当定时器超期后,停止乐观自旋。
如图15所示,图15示出了本申请实施例提供的一种线程持锁方法,该方法实施例中,锁的类型为第二读写锁,所述第二读写锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,本申请实施例用于在等待队列中确定哪些线程可以进入自旋队列进行乐观自旋,具体地,该方法包括:S1501至S1505。
S1501:确定当前待持锁的每个待选线程和所述待持锁的类型。
S1502:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息。
于本申请实施例中,锁的类型为第二读写锁,目标信息包括线程类型和临界区长度,该乐观自旋队列的持锁方式以及与等待队列之间的关系可以参考前述实施例,在此不再赘述。
S1503:基于当前临界区的持锁线程的线程类型,从等待队列中确定至少部分线程进入乐观自旋队列中。
读写锁的乐观自旋概念和互斥锁是类似的,只不过由于在读线程持锁的时候,临界区有多个读线程,这时候如果乐观自旋,那么需要等所有的读线程离开临界区。针对读写锁的乐观自旋队列的优化,可以基于乐观自旋准入控制、写线程位于临界区的超时机制以及Ux线程插队方案等策略考虑。
作为一种实施方式,对于乐观自旋准入控制而言,如果当前临界区的持锁线程的线程类型为读类型,则采用图13所示的实施方式,即如果当前临界区的持锁线程的线程类型为读类型,若所述等待队列中不存在等锁时长大于预设时长的线程,基于各个所述待选线程的线程类型,确定所述等待队列中是否存在与用户感知相关的线程;若所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中。也就是说,基于当前临界区的持锁线程的线程类型,从等待队列中确定至少部分线程进入乐观自旋队列中的实施方式为,若当前临界区的持锁线程的线程类型为写类型,则在确定所述等待队列中不存在等锁时长大于预设时长的线程且所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中,具体地,可以参阅图13的方法的实施方式,在此不再赘述。
作为另一种实施方式,如果当前临界区的持锁线程的线程类型为读类型,则当临界区的读线程小于指定的数量,并且判定所有的读线程的临界区都是短临界区的情况下才允许乐观自旋。也就是说,基于当前临界区的持锁线程的线程类型,从等待队列中确定至少部分线程进入乐观自旋队列中的实施方式为,若当前临界区的持锁线程的线程类型为读类型,且所述持锁线程的数量小于指定数量,则确定所述等待队列中的所有读类型的线程中,是否临界区长度均小于指定长度;若临界区长度均小于指定长度,则将所述等待队列中的线程加入所述乐观自旋队列中;从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
S1504:从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程。
S1505:控制所述目标线程进入目标线程的临界区持锁。
如图16所示,图16示出了本申请实施例提供的一种线程持锁方法,该方法包括:S1601至S1605。
S1601:确定当前待持锁的每个待选线程和所述待持锁的类型。
S1602:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型。
S1603:基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。
S1604:控制所述目标线程进入目标线程的临界区持锁。
S1605:当检测到唤醒线程请求抢占所述目标线程所持有的锁的情况下,确定所述目标线程的持锁时长。
S1606:若所述持锁时长小于预设持锁时长,禁止所述唤醒线程抢占所述目标线程所持有的锁。
在一些重载场景中,临界区的线程经常被新唤醒的线程抢占执行,例如,CPU的运行队列有2个线程,线程A和线程B,当前线程A正在执行,持锁然后进入临界区,还没有释放锁,这时候可能一些异步事件(例如用户输入)唤醒线程C并挂入CPU的运行队列,这时候,线程C就会取代线程A,在CPU执行,线程A还没有释放锁就失去CPU资源,挂入运行队列,等待下次CPU调度执行,即线程A被线程C抢占执行。这延长了持锁临界区的时间长度,进而导致了所有竞争锁的线程有一个较长的持锁时延。
当唤醒一个线程到指定的CPU上执行的时候,原生内核调度器会执行唤醒抢占逻辑,以便确定该被唤醒的任务是否要抢占当前运行在CPU的任务。于本申请实施例中,在线程获取锁和释放锁的位置分别设置和清除一个标记,通过这个标记,可以判断一个线程是否在临界区内执行。为了不影响***关键任务的调度时延,限制了唤醒抢占优化的时间区间,例如可以是1ms。也就是说,当检测到唤醒线程请求抢占所述目标线程所持有的锁的情况下,如果当前的持锁线程的持锁时长小于预设持锁时长,禁止所述唤醒线程抢占所述目标线程所持有的锁。具体地,在线程获取到锁的时刻标记,同时启动一个1ms(预设持锁时长)定时器。在释放锁的时候清除标记,如果定时器没有超时,那么取消定时器。如果有线程抢锁,则判断当前是否有持锁线程,如果没有则按照原生逻辑持锁,如果有持锁线程,并且定时器没有超时,那么禁止抢占,如果有持锁线程,但是定时器已经超时,那么按照原生逻辑持锁。
如图17所示,图17示出了本申请实施例提供的一种线程持锁方法,该方法包括:S1701至S1705。
S1701:确定当前待持锁的每个待选线程和所述待持锁的类型。
S1702:基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型。
S1703:基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。
S1704:控制所述目标线程进入目标线程的临界区持锁。
S1705:若所述目标线程满足预设待优化条件,则控制所述目标线程的运行负载不低于预设负载。
在移动终端内,大部分的临界区都比较短,但是在特定场景中,例如内存压力较大,临界区代码指令条数会非常多。在这样的场景中,如果CPU算力不足那么会导致临界区的时间长度非常长,从而导致等待线程全部长时间的处于等待状态,恶化了持锁时延。虽然,对CPU的提频或采用迁核的操作可以提升执行线程的算力,但是,由于提频和迁核都需要额外的计算开销,因此这个临界区算力优化不能应用在所有的场景,否则会恶化轻竞争烈度的锁竞争场景。
作为一种实施方式,预设待优化条件包括临界区长度大于预设阈值和运行该目标线程的处理器的运行参数满足预设运行条件的至少一种,其中,线程的临界区长度大于预设阈值表征该临界区的代码的指令条数较多,运行该线程的时候,会消耗更多的CPU资源,运行该目标线程的处理器的运行参数满足预设运行条件用于表征该运行该线程的CPU的运算能力不足。示例性地,该运行该目标线程的处理器的运行参数满足预设运行条件包括:运行该目标线程的处理器为小核处理器且运行频率低于指定门限值。作为一种实施方式,电子设备的处理器包括大核处理器和小核处理器,其中,大核处理器相比小核处理器的运算能力更高且功耗也更高。所以,通过该预设条件能够将运算量大及运算量不足的情况涵盖。
因此,本申请实施例所适用的情况包括:当目标线程进入临界区的时候,该目标线程的临界区被判定长临界区,即临界区长度大于预设长度;该线程所在的CPU属于小核CPU并且运行频率低于指定的门限值;仅在特定的锁上使用,因为,有些锁的线程的临界区通常是短临界区,所以不必优化。有些锁的线程,在特定的场景中(例如内存压力非常大的时候)会出现较长临界区。算力优化(提升CPU频率或者迁移到算力更高的CPU上)本身是需要一些开销的,对于短临界区是没有意义的,花费了一定的CPU开销执行了算力优化后,可能临界区都已经执行完成。
因此,该预设待优化条件包括临界区长度大于预设阈值、运行该目标线程的处理器的运行参数满足预设运行条件以及所持有的锁的类型为指定类型的至少一种,其中,该指定类型可以基于实际使用而设定,例如,可以预先统计预设时间段内持有各个类型的锁的线程的对应的临界区长度,并确定每个锁类型对应的短临界区在该锁的所有临界区的占比,如果该占比大于指定数值,则判定该锁为指定类型。其中,该指定数值可以基于实际使用而设定,例如,可以是95%及其以上。
原生的方案是会跟踪持锁线程和运行该线程的CPU的负载,如果CPU的负载较大,就提升CPU的频率,如果CPU的负载较小,就降低CPU的频率。需要说明的是,CPU的负载是CPU上所有任务的负载之和。控制所述目标线程的运行负载不低于预设负载的实施方式为在目标线程满足预设待优化条件的时候,给目标线程分配一个最低的负载门限值,使得运行该目标线程的CPU负载小于这个门限值。
请参阅图18,其示出了本申请实施例提供的一种线程持锁装置1800的结构框图,该装置可以包括:第一确定单元1801、第二确定单元1802、第三确定单元1803和持锁单元1804。
第一确定单元1801,用于确定当前待持锁的每个待选线程和所述待持锁的类型。
第二确定单元1802,用于基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型。
第三确定单元1803,用于基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程。
持锁单元1804,用于控制所述目标线程进入目标线程的临界区持锁。
进一步的,持锁绝限时间为等锁起始时刻与持锁时延阈值之和,持锁时延阈值基于待选线程与用户感知的关联程度而确定,待选线程与用户感知的关联程度与该线程的持锁时延阈值负相关所述临界区长度基于所述临界区的代码指令条数以及该运行该临界区对应的待选线程的处理器的运行参数而确定。
进一步的,所述锁的类型为第一互斥锁,所述目标信息包括等锁时长,所述第一互斥锁对应的等待队列包括第一队列,各个所述待选线程位于所述第一队列内,所述第一队列从队首至队尾的各个线程的等锁时长依次降低,第三确定单元1803还用于将所述第一队列中的队首的线程作为第一线程;从多个所述待选线程中确定等锁时长最大的待选线程,作为第一线程,其中,所述第一线程的持锁优先级最高;若所述第一线程的等锁时长大于预设时长,则将所述第一线程作为目标线程。
进一步的,所述目标信息还包括延时敏感度,所述等待队列还包括第二队列,所述第二队列用于存放各个所述待选线程中与用户相关的线程,所述第二队列从队首至队尾的各个线程的持锁绝限时间依次增大,第三确定单元1803还用于若所述第一线程的等锁时长不大于预设时长,将所述第二队列中的队首的线程作为目标线程。
进一步的,目标信息还包括临界区长度,所述等待队列包括第三队列,各个所述待选线程位于所述第三队列内,所述第三队列从队首至队尾的各个线程的临界区长度依次增大,第三确定单元1803还用于若所述第一线程的等锁时长不大于预设时长且所述第二队列中不存在线程,则将所述第三队列中的队首的线程作为目标线程。
进一步的,待持锁的类型为自旋锁,所述目标信息包括等锁时长和临界区长度,多个所述待选线程位于所述自旋锁对应的自旋队列中,第三确定单元1803还用于若多个所述待选线程中存在临界区长度小于预设长度的待选线程,则从该临界区长度小于预设长度的待选线程中确定等锁时长最大的待选线程作为目标线程。
进一步的,自旋队列包括主自旋队列,所述主自旋队列用于存放各个所述待选线程中临界区长度小于预设长度的线程,且所述主自旋队列从队首至队尾的各个线程的等锁时长依次降低,第三确定单元1803还用于若所述主自旋队列中存在临界区长度小于预设长度的线程线程,则将所述主自旋队列的队首的线程作为所述目标线程,其中,所述目标线程的持锁优先级最高。
进一步的,第三确定单元1803还用于若多个所述待选线程中不存在临界区长度小于预设长度的线程,则从多个所述待选线程中确定临界区长度不小于预设长度的线程且等锁时长最大的线程作为目标线程。
进一步的,自旋队列包括主自旋队列和副自旋队列,所述主自旋队列用于存放各个所述待选线程中临界区长度小于预设长度的线程,所述副自旋队列用于存放各个所述待选线程中临界区长度不小于预设长度的线程,且所述主自旋队列和副自旋队列均为从队首至队尾的各个线程的等锁时长依次降低,第三确定单元1803还用于若所述主自旋队列中不存在线程,则将所述副自旋队列的队首的线程作为所述目标线程。
进一步的,待持锁的类型为第一读写锁,所述目标信息包括线程类型,多个所述待选线程位于所述读写锁对应的等待队列中,第三确定单元1803还用于在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程,作为第三线程;若所述第三线程与用户感知相关且线程类型是读类型,则将所述第三线程作为目标线程,其中,所述目标线程的持锁优先级最高。
进一步的,目标信息还包括等锁时长,第三确定单元1803还用于若所述第三线程与用户感知相关且线程类型是读类型,则在所述等待队列中不存在等锁时长大于预设时长的线程且当前临界区内读类型的线程不大于预设最大值的情况下,将所述第三线程作为目标线程。
进一步的,第三确定单元1803还用于等待队列内的各个线程基于从队首至队尾的顺序进入临界区,所述在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程之前,在所述等待队列中按照从队首至队尾的第一方向,查找第一个等锁时长小于预设时长的线程,作为第四线程;基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中。
进一步的,第三确定单元1803还用于若当前待持锁的所述待选线程的线程类型为读类型,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第一线程组;将所述待选线程***所述第一线程组的任意位置;若当前待持锁的所述待选线程的线程类型为读类型,且所述第四线程的线程类型为写类型,则将沿所述第一方向上所述第四线程之后的相邻的所有读类型的线程,作为第二线程组;将所述待选线程***所述第二线程组的任意位置。
进一步的,第三确定单元1803还用于若当前待持锁的所述待选线程的线程类型为写类型,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第三线程组;将所述待选线程***所述第一线程组的最靠近所述队首的位置;若当前待持锁的所述待选线程的线程类型为写类型,且所述第四线程的线程类型为写类型,则沿所述第一方向将所述待选线程***所述第四线程的前一个位置且与所述第四线程相邻。
进一步的,待持锁的类型为第二互斥锁,所述第二互斥锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和等锁时长,第三确定单元1803还用于若所述等待队列中不存在等锁时长大于预设时长的线程,基于各个所述待选线程的线程类型,确定所述等待队列中是否存在与用户感知相关的线程;若所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中;从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
进一步的,待持锁的类型为第二读写锁,所述第二读写锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和临界区长度,第三确定单元1803还用于若当前临界区的持锁线程的线程类型为写类型,则在确定所述等待队列中不存在等锁时长大于预设时长的线程且所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中;从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
进一步的,所述待持锁的类型为第二读写锁,所述读写锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和临界区长度,第三确定单元1803还用于若当前临界区的持锁线程的线程类型为读类型,且所述持锁线程的数量小于指定数量,则确定所述等待队列中的所有读类型的线程中,是否临界区长度均小于指定长度;若临界区长度均小于指定长度,则将所述等待队列中的线程加入所述乐观自旋队列中;从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
进一步的,持锁单元1804还用于当检测到唤醒线程请求抢占所述目标线程所持有的锁的情况下,确定所述目标线程的持锁时长;若所述持锁时长小于预设持锁时长,禁止所述唤醒线程抢占所述目标线程所持有的锁。
进一步的,持锁单元1804还用于若所述目标线程满足预设待优化条件,则控制所述目标线程的运行负载不低于预设负载,其中,所述预设待优化条件包括临界区长度大于预设阈值和运行该目标线程的处理器的运行参数满足预设运行条件的至少一种。
进一步的,所述运行该目标线程的处理器的运行参数满足预设运行条件包括:运行该目标线程的处理器为小核处理器且运行频率低于指定门限值。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述装置和模块的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
在本申请所提供的几个实施例中,模块相互之间的耦合可以是电性,机械或其它形式的耦合。
另外,在本申请各个实施例中的各功能模块可以集成在一个处理模块中,也可以是各个模块单独物理存在,也可以两个或两个以上模块集成在一个模块中。上述集成的模块既可以采用硬件的形式实现,也可以采用软件功能模块的形式实现。
请参考图19,其示出了本申请实施例提供的一种电子设备的结构框图。该电子设备100可以是智能手机、平板电脑、电子书等能够运行应用程序的电子设备。本申请中的电子设备100可以包括一个或多个如下部件:处理器110、存储器120、以及一个或多个应用程序,其中一个或多个应用程序可以被存储在存储器120中并被配置为由一个或多个处理器110执行,一个或多个程序配置用于执行如前述方法实施例所描述的方法。
处理器110可以包括一个或者多个处理核。处理器110利用各种接口和线路连接整个电子设备100内的各个部分,通过运行或执行存储在存储器120内的指令、程序、代码集或指令集,以及调用存储在存储器120内的数据,执行电子设备100的各种功能和处理数据。可选地,处理器110可以采用数字信号处理(Digita l Signa l Process ing,DSP)、现场可编程门阵列(Fie ld-Programmab le Gate Array,FPGA)、可编程逻辑阵列(Programmab leLogic Array,PLA)中的至少一种硬件形式来实现。处理器110可集成中央处理器(Centra lProcess ing Un it,CPU)、图像处理器(Graph ics Process i ng Un it,GPU)和调制解调器等中的一种或几种的组合。其中,CPU主要处理操作***、用户界面和应用程序等;GPU用于负责显示内容的渲染和绘制;调制解调器用于处理无线通信。可以理解的是,上述调制解调器也可以不集成到处理器110中,单独通过一块通信芯片进行实现。
存储器120可以包括随机存储器(Random Access Memory,RAM),也可以包括只读存储器(Read-On ly Memory)。存储器120可用于存储指令、程序、代码、代码集或指令集。存储器120可包括存储程序区和存储数据区,其中,存储程序区可存储用于实现操作***的指令、用于实现至少一个功能的指令(比如触控功能、声音播放功能、图像播放功能等)、用于实现下述各个方法实施例的指令等。存储数据区还可以存储电子设备100在使用中所创建的数据(比如电话本、音视频数据、聊天记录数据)等。
请参考图20,其示出了本申请实施例提供的一种计算机可读介质的结构框图。该计算机可读介质2000中存储有程序代码,所述程序代码可被处理器调用执行上述方法实施例中所描述的方法。
计算机可读介质2000可以是诸如闪存、EEPROM(电可擦除可编程只读存储器)、EPROM、硬盘或者ROM之类的电子存储器。可选地,计算机可读介质2000包括非易失性计算机可读介质(non-trans itory computer-readab le storage med ium)。计算机可读介质2000具有执行上述方法中的任何方法步骤的程序代码2010的存储空间。这些程序代码可以从一个或者多个计算机程序产品中读出或者写入到这一个或者多个计算机程序产品中。程序代码2010可以例如以适当形式进行压缩。
综上所述,对于当前待持锁的待选线程,确定该待选线程请求持的锁的类型,然后,基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁时延阈值和线程类型,基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;控制所述目标线程进入目标线程的临界区持锁。也就是说,所确定的可以持锁的线程的参考依据可以包括等锁时长、临界区长度、持锁时延阈值和线程类型等因素,参考的因素较丰富,能够较好地从多个待持锁的线程中确定可持锁的线程。
(1)通过对不同长度临界区的重排,提高了锁的吞吐量。(2)通过对Ux线程和Non-ux线程在锁队列中的重排,大大提升了Ux线程的持锁时延,与此同时,也兼顾的整个***的最大持锁时延。(3)通过对临界区线程进行资源的优化,缩短了持锁线程的临界区执行时间,从而提升了整体锁的吞吐量。(4)通过对睡眠锁乐观自旋的优化,提高了乐观自旋的效率,提升了移动终端的续航性能。
最后应说明的是:以上实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不驱使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围。
Claims (24)
1.一种线程持锁方法,其特征在于,包括:
确定当前待持锁的每个待选线程和所述待持锁的类型;
基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型;
基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;
控制所述目标线程进入目标线程的临界区持锁。
2.根据权利要求1所述的方法,其特征在于,所述持锁绝限时间为等锁起始时刻与持锁时延阈值之和,持锁时延阈值基于待选线程与用户感知的关联程度而确定,待选线程与用户感知的关联程度与该线程的持锁时延阈值负相关。
3.根据权利要求1所述的方法,其特征在于,所述临界区长度基于所述临界区的代码指令条数以及运行该临界区对应的待选线程的处理器的运行参数而确定。
4.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为第一互斥锁,所述目标信息包括等锁时长,所述第一互斥锁对应的等待队列包括第一队列,各个所述待选线程位于所述第一队列内,所述第一队列从队首至队尾的各个线程的等锁时长依次降低,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个所述待选线程作为目标线程,包括:
将所述第一队列中的队首的线程作为第一线程;
若所述第一线程的等锁时长大于预设时长,则将所述第一线程作为目标线程。
5.根据权利要求4所述的方法,其特征在于,所述目标信息还包括延时敏感度,所述等待队列还包括第二队列,所述第二队列用于存放各个所述待选线程中与用户相关的线程,所述第二队列从队首至队尾的各个线程的持锁绝限时间依次增大,所述方法还包括:
若所述第一线程的等锁时长不大于预设时长,将所述第二队列中的队首的线程作为目标线程。
6.根据权利要求5所述的方法,其特征在于,所述目标信息还包括临界区长度,所述等待队列包括第三队列,各个所述待选线程位于所述第三队列内,所述第三队列从队首至队尾的各个线程的临界区长度依次增大,所述方法,还包括:
若所述第一线程的等锁时长不大于预设时长且所述第二队列中不存在线程,则将所述第三队列中的队首的线程作为目标线程。
7.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为自旋锁,所述目标信息包括等锁时长和临界区长度,多个所述待选线程位于所述自旋锁对应的自旋队列中,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个所述待选线程作为目标线程,包括:
若多个所述待选线程中存在临界区长度小于预设长度的待选线程,则从该临界区长度小于预设长度的待选线程中确定等锁时长最大的待选线程作为目标线程。
8.根据权利要求7所述的方法,其特征在于,所述自旋队列包括主自旋队列,所述主自旋队列用于存放各个所述待选线程中临界区长度小于预设长度的线程,且所述主自旋队列从队首至队尾的各个线程的等锁时长依次降低,所述从多个所述待选线程中确定临界区长度小于预设长度的且等锁时长最大的线程作为目标线程,包括:
若所述主自旋队列中存在临界区长度小于预设长度的线程线程,则将所述主自旋队列的队首的线程作为所述目标线程,其中,所述目标线程的持锁优先级最高。
9.根据权利要求7所述的方法,其特征在于,还包括:
若多个所述待选线程中不存在临界区长度小于预设长度的线程,则从多个所述待选线程中确定临界区长度不小于预设长度的线程且等锁时长最大的线程作为目标线程。
10.根据权利要求9所述的方法,其特征在于,所述自旋队列包括主自旋队列和副自旋队列,所述主自旋队列用于存放各个所述待选线程中临界区长度小于预设长度的线程,所述副自旋队列用于存放各个所述待选线程中临界区长度不小于预设长度的线程,且所述主自旋队列和副自旋队列均为从队首至队尾的各个线程的等锁时长依次降低,所述若多个所述待选线程中不存在临界区长度小于预设长度的线程,则从多个所述待选线程中确定临界区长度不小于预设长度的线程且等锁时长最大的线程作为目标线程,包括:
若所述主自旋队列中不存在线程,则将所述副自旋队列的队首的线程作为所述目标线程。
11.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为第一读写锁,所述目标信息包括线程类型,多个所述待选线程位于所述第一读写锁对应的等待队列中,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个所述待选线程作为目标线程,包括:
在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程,作为第三线程;
若所述第三线程与用户感知相关且线程类型是读类型,则将所述第三线程作为目标线程,其中,所述目标线程的持锁优先级最高。
12.根据权利要求11所述的方法,其特征在于,所述目标信息还包括等锁时长,所述若所述第三线程与用户感知相关且线程类型是读类型,则将所述第三线程作为目标线程,包括:
若所述第三线程与用户感知相关且线程类型是读类型,则在所述等待队列中不存在等锁时长大于预设时长的线程且当前临界区内读类型的线程不大于预设最大值的情况下,将所述第三线程作为目标线程。
13.根据权利要求11所述的方法,其特征在于,所述等待队列内的各个线程基于从队首至队尾的顺序进入临界区,所述在当前临界区内的线程类型均为读类型且所述等待队列中存在写类型的线程时,确定所述等待队列中请求持锁的待选线程之前,还包括:
在所述等待队列中按照从队首至队尾的第一方向,查找第一个等锁时长小于预设时长的线程,作为第四线程;
基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中。
14.根据权利要求13所述的方法,其特征在于,所述基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中,包括:
若当前待持锁的所述待选线程的线程类型为读类型,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第一线程组;
将所述待选线程***所述第一线程组的任意位置;
若当前待持锁的所述待选线程的线程类型为读类型,且所述第四线程的线程类型为写类型,则将沿所述第一方向上所述第四线程之后的相邻的所有读类型的线程,作为第二线程组;
将所述待选线程***所述第二线程组的任意位置。
15.根据权利要求13所述的方法,其特征在于,所述基于当前待持锁的所述待选线程的线程类型以及所述第四线程的线程类型,将所述待选线程***所述等待队列中,包括:
若当前待持锁的所述待选线程的线程类型为写类型,且所述第四线程的线程类型为读类型,则确定与所述第四线程相邻的所有读类型的线程,作为第三线程组;
将所述待选线程***所述第三线程组的最靠近所述队首的位置;
若当前待持锁的所述待选线程的线程类型为写类型,且所述第四线程的线程类型为写类型,则沿所述第一方向将所述待选线程***所述第四线程的前一个位置且与所述第四线程相邻。
16.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为第二互斥锁,所述第二互斥锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和等锁时长,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程,包括:
若所述等待队列中不存在等锁时长大于预设时长的线程,基于各个所述待选线程的线程类型,确定所述等待队列中是否存在与用户感知相关的线程;
若所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中;
从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
17.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为第二读写锁,所述第二读写锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和等锁时长,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程,包括:
若当前临界区的持锁线程的线程类型为写类型,则在确定所述等待队列中不存在等锁时长大于预设时长的线程且所述等待队列中存在与用户感知相关的线程,将与用户感知相关的线程加入所述乐观自旋队列中;
从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
18.根据权利要求1-3任一所述的方法,其特征在于,所述待持锁的类型为第二读写锁,所述第二读写锁对应有乐观自旋队列和等待队列,各个所述待选线程位于所述等待队列中,所述目标信息包括线程类型和临界区长度,所述基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程,包括:
若当前临界区的持锁线程的线程类型为读类型,且所述持锁线程的数量小于指定数量,则确定所述等待队列中的所有读类型的线程中,是否临界区长度均小于指定长度;
若临界区长度均小于指定长度,则将所述等待队列中的线程加入所述乐观自旋队列中;
从所述乐观自旋队列中确定至少一个所述待选线程作为目标线程,其中,所述目标线程的持锁优先级最高。
19.根据权利要求1-3任一所述的方法,其特征在于,所述控制所述目标线程进入目标线程的临界区持锁之后,还包括:
当检测到唤醒线程请求抢占所述目标线程所持有的锁的情况下,确定所述目标线程的持锁时长;
若所述持锁时长小于预设持锁时长,禁止所述唤醒线程抢占所述目标线程所持有的锁。
20.根据权利要求1-3任一所述的方法,其特征在于,所述控制所述目标线程进入目标线程的临界区持锁之后,还包括:
若所述目标线程满足预设待优化条件,则控制所述目标线程的运行负载不低于预设负载,其中,所述预设待优化条件包括临界区长度大于预设阈值和运行该目标线程的处理器的运行参数满足预设运行条件的至少一种。
21.根据权利要求20所述的方法,其特征在于,所述运行该目标线程的处理器的运行参数满足预设运行条件包括:运行该目标线程的处理器为小核处理器且运行频率低于指定门限值。
22.一种线程持锁装置,其特征在于,包括:
第一确定单元,用于确定当前待持锁的每个待选线程和所述待持锁的类型;
第二确定单元,用于基于所述待持锁的类型从每个所述待选线程对应的多个属性信息中确定至少一个属性信息,作为目标信息,其中,所述多个属性信息包括等锁时长、临界区长度、持锁绝限时间和线程类型;
第三确定单元,用于基于各个所述待选线程的目标信息,从多个所述待选线程中确定至少一个持锁优先级满足预设条件的所述待选线程作为目标线程;
持锁单元,用于控制所述目标线程进入目标线程的临界区持锁。
23.一种电子设备,其特征在于,包括:
一个或多个处理器;
存储器;
一个或多个应用程序,其中所述一个或多个应用程序被存储在所述存储器中并被配置为由所述一个或多个处理器执行,所述一个或多个应用程序配置用于执行如权利要求1-21任一项所述的方法。
24.一种计算机可读介质,其特征在于,所述计算机可读介质存储有处理器可执行的程序代码,所述程序代码被所述处理器执行时使所述处理器执行权利要求1-21任一项所述方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211699161.5A CN115904744A (zh) | 2022-12-28 | 2022-12-28 | 线程持锁方法、装置、电子设备及计算机可读介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211699161.5A CN115904744A (zh) | 2022-12-28 | 2022-12-28 | 线程持锁方法、装置、电子设备及计算机可读介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115904744A true CN115904744A (zh) | 2023-04-04 |
Family
ID=86483895
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202211699161.5A Pending CN115904744A (zh) | 2022-12-28 | 2022-12-28 | 线程持锁方法、装置、电子设备及计算机可读介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115904744A (zh) |
-
2022
- 2022-12-28 CN CN202211699161.5A patent/CN115904744A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
JP3987384B2 (ja) | 実行キュー管理 | |
JP4694595B2 (ja) | スリープキュー管理 | |
EP3008594B1 (en) | Assigning and scheduling threads for multiple prioritized queues | |
US8959515B2 (en) | Task scheduling policy for limited memory systems | |
US9201693B2 (en) | Quota-based resource management | |
US8615765B2 (en) | Dividing a computer job into micro-jobs | |
CN108549574B (zh) | 线程调度管理方法、装置、计算机设备和存储介质 | |
US10271326B2 (en) | Scheduling function calls | |
CN111488210B (zh) | 基于云计算的任务调度方法、装置和计算机设备 | |
CN109117280B (zh) | 电子装置及其限制进程间通信的方法、存储介质 | |
CN111897637B (zh) | 作业调度方法、装置、主机及存储介质 | |
CN107515781B (zh) | 一种基于多处理器的确定性任务调度及负载均衡*** | |
CN109117279B (zh) | 电子装置及其限制进程间通信的方法、存储介质 | |
CN112764904A (zh) | 基于多任务***中防止低优先级任务饿死的方法 | |
CN112925616A (zh) | 任务分配方法、装置、存储介质及电子设备 | |
CN111597044A (zh) | 任务调度方法、装置、存储介质及电子设备 | |
EP2840513A1 (en) | Dynamic task prioritization for in-memory databases | |
CN115904744A (zh) | 线程持锁方法、装置、电子设备及计算机可读介质 | |
KR101377195B1 (ko) | 컴퓨터 마이크로 작업 | |
CN116932227B (zh) | 一种基于单线程的任务调度方法及装置 | |
Liu | Efficient design, analysis, and implementation of complex multiprocessor real-time systems | |
EP2595057B1 (en) | Modified backfill scheduler and a method employing frequency control to reduce peak cluster power requirements | |
CN115543564A (zh) | Io请求的处理方法、装置、电子设备及存储介质 | |
CN113687930A (zh) | 支持自动晋升的任务管理方法、装置、设备及存储介质 | |
Buchanan et al. | Processes and Scheduling |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |