发明内容
有鉴于此,本公开实施例至少提供一种程序死锁的检测方法及装置、计算机设备及存储介质。
本公开主要包括以下几个方面:
第一方面,本公开实施例提供一种程序死锁的检测方法,所述程序死锁的检测方法包括:获取目标程序各线程的资源调用信息;其中,所述线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及所述目标调用资源对应资源锁的目标线程;基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图;其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;基于所述有向图,确定所述目标程序的死锁检测结果。
在一种可能的实施方式中,所述检测方法还包括:基于多个处于被调用状态的资源锁、所述资源锁对应的资源、以及调用所述资源锁的目标线程,生成资源调用记录;所述获取目标程序各线程的资源调用信息,包括:
基于各所述线程对应的资源调用记录,确定是否存在与所述目标调用资源对应的资源锁;若所述资源调用记录中存在与所述目标调用资源对应的资源锁,基于与所述目标调用资源对应资源锁的当前调用线程,确定各所述线程的资源调用信息。
在一种可能的实施方式中,所述基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图,包括:生成所述目标程序各所述线程分别对应的节点;针对每个节点,根据所述每个节点对应的线程持有的当前调用资源,在资源调用记录中添加所述当前调用资源的资源锁被所述每个节点拥有的记录;确定所述资源调用记录中,是否存在所述每个节点的目标调用资源的资源锁;在存在的情况下,生成从所述每个节点到所述目标节点的有向边。
在一种可能的实施方式中,所述基于所述有向图,确定所述目标程序的死锁检测结果,包括:基于所述有向图,确定所述有向图中是否存在由所述节点、以及所述有向边构成的有向环;若存在,则确定所述目标程序存在线程死锁。
在一种可能的实施方式中,所述获取目标程序各线程的资源调用信息,包括:周期性地获取目标程序的多个线程中每个线程的资源调用信息;或者,在预设的程序死锁检测事件被触发后,获取目标程序的多个线程中每个线程的资源调用信息。
在一种可能的实施方式中,所述程序死锁检测事件包括下述至少一种:所述多个线程中的任一线程请求调用第一目标资源;所述多个线程中的任一线程对所述第一目标资源调用失败。
在一种可能的实施方式中,所述基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图之后,还包括:在预设的有向图更新事件被触发后,更新所述有向图;其中,所述有向图更新事件包括:线程和/或线程的资源调用信息发生改变。
在一种可能的实施方式中,当所述有向图更新事件为线程发生改变时,所述在预设的有向图更新事件被触发后,更新所述有向图,包括:当取消和/或关闭线程时,删除所述有向图中的与所述线程对应的节点;当创建线程时,添加所述有向图中的与所述线程对应的节点。
在一种可能的实施方式中,当所述有向图更新事件为线程的资源调用信息发生改变时,所述在预设的有向图更新事件被触发后,更新所述有向图,包括:所述线程释放当前调用资源的资源锁;所述线程请求调用第二目标资源,并且所述线程对所述第二目标资源调用失败。
在一种可能的实施方式中,所述检测方法还包括:基于由所述节点、以及所述有向边构成的有向环,确定与所述有向环中多个节点对应的多个线程为发生死锁的目标线程。
在一种可能的实施方式中,在确定存在线程死锁之后,所述检测方法还包括:释放多个所述目标线程中的第一目标线程当前调用的目标资源;其中,所述目标资源为多个所述目标线程中的第二目标线程请求调用的所述第一目标资源。
第二方面,本公开实施例还提供一种程序死锁的检测装置,所述检测装置包括:获取模块、绘制模块以及第一确定模块;
所述获取模块,用于获取目标程序各线程的资源调用信息;其中,所述线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及所述目标调用资源对应资源锁的目标线程;
所述绘制模块,用于基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图;其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;
所述第一确定模块,用于基于所述有向图,确定所述目标程序的死锁检测结果。
在一种可能的实施方式中,所述检测装置还包括:生成模块;
所述生成模块,用于基于多个处于被调用状态的资源锁、所述资源锁对应的资源、以及调用所述资源锁的目标线程,生成资源调用记录。
所述获取模块具体用于:基于各线程对应的资源调用记录,确定是否存在与所述目标调用资源对应的资源锁;若所述资源调用记录中存在与所述目标调用资源对应的资源锁,基于与所述目标调用资源对应资源锁的当前调用线程,确定各的资源调用信息。
在一种可能的实施方式中,所述绘制模块具体用于:生成所述目标程序中各个线程分别对应的节点;针对每个节点,根据所述每个节点对应的线程持有的当前调用资源,在资源调用记录中添加所述当前调用资源的资源锁被所述每个节点拥有的记录;确定所述资源调用记录中,是否存在所述每个节点的目标调用资源的资源锁;在存在的情况下,生成从所述每个节点到所述目标节点的有向边。
在一种可能的实施方式中,所述第一确定模块具体用于:基于所述有向图,确定所述有向图中是否存在由所述节点、以及所述有向边构成的有向环;若存在,则确定所述目标程序存在线程死锁。
在一种可能的实施方式中,所述获取模块还用于:周期性地获取目标程序的多个线程中每个线程的资源调用信息;或者,在预设的程序死锁检测事件被触发后,获取目标程序的多个线程中每个线程的资源调用信息。
在一种可能的实施方式中,所述程序死锁检测事件包括下述至少一种:所述多个线程中的任一线程请求调用第一目标资源;所述多个线程中的任一线程对所述第一目标资源调用失败。
在一种可能的实施方式中,所述检测装置还包括:更新模块;
所述更新模块,用于在预设的有向图更新事件被触发后,更新所述有向图;其中,所述有向图更新事件包括:线程和/或线程的资源调用信息发生改变。
在一种可能的实施方式中,所述更新模块具体用于:当取消和/或关闭线程时,删除所述有向图中的与所述线程对应的节点;当创建线程时,添加所述有向图中的与所述线程对应的节点。
在一种可能的实施方式中,所述更新模块还用于:所述线程释放当前调用资源的资源锁;所述线程请求调用第二目标资源,并且所述线程对所述第二目标资源调用失败。
在一种可能的实施方式中,所述检测装置还包括:第二确定模块;
第二确定模块,用于基于由所述节点、以及所述有向边构成的有向环,确定与所述有向环中多个节点对应的多个线程为发生死锁的目标线程。
在一种可能的实施方式中,所述检测装置还包括:释放模块;
所述释放模块,用于释放多个所述目标线程中的第一目标线程当前调用的目标资源;其中,所述目标资源为多个所述目标线程中的第二目标线程请求调用的所述第一目标资源。
第三方面,本公开实施例还提供一种计算机设备,包括:相互连接的处理器和存储器,所述存储器存储有所述处理器可执行的机器可读指令,当计算机设备运行时,所述机器可读指令被所述处理器执行时执行上述第一方面,或第一方面中任一种可能的实施方式中的步骤。
第四方面,本公开实施例还提供一种计算机可读存储介质,该计算机可读存储介质上存储有计算机程序,该计算机程序被处理器运行时执行上述第一方面,或第一方面中任一种可能的实施方式中的步骤。
本公开实施例通过获取目标程序各线程的资源调用信息;其中,线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及目标调用资源对应资源锁的目标线程;基于各线程的资源调用信息,绘制多个线程之间的有向图;其中,有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;基于有向图,确定目标程序的死锁检测结果,从而能够根据生成的有向图,更加快速地检测出程序是否发生死锁,提高对于程序检测的效率与准确率。
进一步的,通过绘制的有向图,可以快速确定程序中发生死锁的线程,从而可以通过调整对应线程的调用函数解决程序死锁的问题,提高了解决程序死锁问题的效率。
为使本申请的上述目的、特征和优点能更明显易懂,下文特举较佳实施例,并配合所附附图,作详细说明如下。
具体实施方式
为使本公开实施例的目的、技术方案和优点更加清楚,下面将结合本公开实施例中附图,对本公开实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。通常在此处附图中描述和示出的本公开实施例的组件可以以各种不同的配置来布置和设计。因此,以下对在附图中提供的本申请的实施例的详细描述并非旨在限制要求保护的本申请的范围,而是仅仅表示本申请的选定实施例。基于本申请的实施例,本领域技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本申请保护的范围。
经研究发现,通常采用的线程死锁检测方法为:当应用程序的主线程失去响应达到预设的时长,且在预设时长后应用程序崩溃,那么认为此时程序发生了线程死锁。由于应用程序崩溃的原因较多,因此无法确定程序崩溃是否是由于发生了线程死锁而导致的,因此这种检测方式的误判率较高,且由于只有在主线程发生死锁时,才能够发生程序崩溃,因此无法检测到无主线程参与线程死锁问题,即无法检测到次线程的死锁情况,因此该检测方法的效率较低。
基于上述研究,本公开实施例提出一种程序死锁的检测方法,能够利用目标程序中各线程分别对应的资源调用信息,生成有向图,并根据生成的有向图,更加快速地检测出程序是否发生死锁,提高对于程序检测的效率与准确率。
针对上述问题的发现过程以及本公开针对上述问题所提出的解决方案,都应该是发明人在本公开过程中对本公开做出的贡献。
下面将结合本公开中附图,对本公开中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本公开一部分实施例,而不是全部的实施例。通常在此处附图中描述和示出的本公开的组件可以以各种不同的配置来布置和设计。因此,以下对在附图中提供的本公开的实施例的详细描述并非旨在限制要求保护的本公开的范围,而是仅仅表示本公开的选定实施例。基于本公开的实施例,本领域技术人员在没有做出创造性劳动的前提下所获得的所有其它实施例,都属于本公开保护的范围。
应注意到:相似的标号和字母在下面的附图中表示类似项,因此,一旦某一项在一个附图中被定义,则在随后的附图中不需要对其进行进一步定义和解释。
本公开实施例所提供的程序死锁的检测方法的执行主体一般为具有一定计算能力的计算机设备,该计算机设备例如包括:终端设备或服务器或其它处理设备,终端设备可以为用户设备(User Equipment,UE)、移动设备、用户终端、终端、蜂窝电话、无绳电话、个人数字助理(Personal Digital Assistant,PDA)、手持设备、计算设备、车载设备、可穿戴设备等。在一些可能的实现方式中,该程序死锁的检测方法可以通过处理器调用存储器中存储的计算机可读指令的方式来实现。
下面以执行主体为用户设备为例对本公开实施例提供的程序死锁的检测方法加以说明。
参见图1所示,为本公开实施例提供的程序死锁的检测方法的流程图,所述检测方法包括步骤S101~S103,其中:
S101:获取目标程序各线程的资源调用信息;其中,所述线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及所述目标调用资源对应资源锁的目标线程;
S102:基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图;其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;
S103:基于所述有向图,确定所述目标程序的死锁检测结果。
下面分别对上述S101~S103分别加以详细说明。
一:在上述S101中,对于一个程序而言,线程是程序中代码执行的最小单位,当一个目标程序启动后,便会有至少一个线程在运行,以保证目标程序的正常运行。
在线程运行时,通常需要调用一些资源,以达到操作目的。但是,当线程需要调用一些共享资源时,若存在多个线程同时调用该共享资源,则会造成一定的资源竞争,由此,当一个共享资源在多个线程或者进程中被同时调用,造成该共享资源可能被多个线程同时修改,导致数据的可靠性无法得到保证。此外,在程序运行时,互相协作的线程之间可能共享一些彼此都能调用的共享资源,但是线程之间对应于该共享资源的调用顺序具有一定的限定,因为,若多个线程同时调用该共享资源时,会造成调用顺序混乱或冲突,从而引发线程之间不同步的问题。
为了解决上述问题,通常会采用对该共享资源进行加锁的方式,以确保该共享资源在被某个线程调用的时候,不会再被其它的线程调用,从而克服数据的可靠性差和调用顺序冲突问题。
在本公开实施例中,还可以基于多个处于被调用状态的资源锁、所述资源锁对应的资源、以及调用所述资源锁的目标线程,生成资源调用记录。
具体的,以处于被调用状态的资源锁为基准,获取该资源所对应的线程状态,即资源锁对应的当前调用资源、以及想要调用该资源锁的目标线程,并基于此进行记录生成资源调用记录。
示例性的,在目标程序后台中,可以以数据字典的形式保存一资源调用记录,该资源调用记录中包括多个当前已经被调用的资源、以及每个被调用资源对应的资源锁的当前调用线程。例如,若A线程当前调用的为α资源,则可以在该资源调用记录中记录“A-α”,以表示出该α资源当前被A线程调用。
此时,在获取目标程序的各线程的当前调用资源时,例如可以针对所述每个线程,基于所各线程对应的资源调用记录中,确定是否存在与所述目标调用资源对应的资源锁。
若所述资源调用记录中存在与所述目标调用资源对应的资源锁,基于与所述目标调用资源对应资源锁的当前调用线程,确定各的资源调用信息。
对于一个线程而言,在其想要调用一目标资源,记作第一目标资源时,可能存在下述两种情况中任一种:该线程想要调用的第一目标资源已被其他线程调用,或者该线程想要调用的第一目标资源未被调用,下面对上述两种情况分开进行阐述:
(1)在该线程想要调用的第一目标资源未被调用的情况下,则该线程可直接调用该第一目标资源,并在资源调用记录添加对应记录。
具体的,在该线程调用所述第一目标资源成功后,更新与该线程及所述第一目标资源对应的资源调用记录,以供后续的处理过程。
示例性的,若A线程当前调用了α资源,则可以在该资源调用记录中添加记录“A-α”,以表示出该α资源当前被A线程调用。或者,若A线程由调用α资源转变为调用β资源,则可以在该资源调用记录中更新记录“A-β”,以表示出该β资源当前转变为被A线程调用。
(2)在该线程想要调用的第一目标资源已被其他线程调用的情况下,即该线程调用所述第一目标资源失败后,通过资源调用记录,从资源调用记录中查找与第一目标资源属于同一资源的第二目标资源,并将查找到的第二目标资源的当前调用线程,确定为用于该线程对应的目标线程。
示例性的,当A线程想要调用α资源,但是α资源未能被成功调用,因此可以判断出该资源目前被其他线程所调用。当需要确定出该资源当前被哪个线程调用时,可以通过在资源调用记录中查找该目标资源的当前被调用线程,即目标线程。以上述举例为例,若在资源调用记录中查找该A资源的当前被目标线程B线程所调用,则可以得到例如“A-α-B”形式的记录,以表征当前目标调用的逻辑关系,也即A线程的资源调用信息。
此外,在本公开另一实施例中,当任一成功调用资源锁的线程释放所述资源锁后,更新与该线程及所述资源锁对应的资源调用记录。此外,当某一资源被删除时,也需要对应更新资源调用记录。
示例性的,若A线程释放了α资源,则可以在该资源调用记录中删除对应的记录“A-α”,以方便后续的记录过程。若α资源被删除,无法被调用时,则在资源调用记录中删除与该资源对应的全部信息。
另外,在本公开另一示例中,可以周期性的获取目标程序的多个线程中每个线程的资源调用信息;在该种情况下,会周期性的基于多个线程分别对应的资源调用信息,绘制多个线程之间的有向图,从而能够周期性的对程序是否死锁进行检测。
在另一种可能的实施方式中,还可以在预设的程序死锁检测事件被触发后,获取目标程序的多个线程中每个线程的资源调用信息。在该种情况下,能够在预设的程序死锁检测事件被触发后,基于程序死锁事件被触发后即时获取多个线程分别对应的资源调用信息,并绘制在该种情况下的有向图,从而能在每当可能造成线程死锁的时候即进行及时的程序死锁的检测。
其中,所述程序死锁检测事件包括下述至少一种:
所述多个线程中的任一线程请求调用第一目标资源;
所述多个线程中的任一线程对所述第一目标资源调用失败。
示例性的,在程序检测到一线程想要调用第三资源,或是线程发出调用第一目标资源的请求时,便可以触发程序死锁检测事件。或是,在任一线程想要调用第一目标资源,但未成功调用时,触发程序死锁检测事件。
在触发程序死锁检测事件之后,便可对当前资源被各个线程的调用情况进行检测,得到各个线程的资源调用信息,并基于多个线程分别对应的资源调用信息,绘制多个线程之间的有向图。
二:在上述S102中,在获取到多个线程对应的资源调用信息之后,便可以基于该信息得到与多个线程对应的有向图。其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边。
具体的,所述基于所述各线程的资源调用信息,绘制多个所述线程之间的有向图,包括:
生成所述目标程序中各个线程分别对应的节点;
针对每个节点,根据所述每个节点对应的线程持有的当前调用资源,在资源调用记录中添加所述当前调用资源的资源锁被所述每个节点拥有的记录;
确定所述资源调用记录中,是否存在所述每个节点的目标调用资源的资源锁;在存在的情况下,生成从所述每个节点到所述目标节点的有向边。
参加图2a和图2b所示,图2a为本公开实施例所提供的有向图构建流程的示意图之一;图2b为本公开实施例所提供的有向图构建流程的示意图之二。
在本公开实施例中,如图2a所示,可以将多个线程分别确定为多个节点。
如图2b所示,针对于有向图中有向边的确定方法如下:获取上述过程中确定的资源调用信息,即当前处理线程与目标线程之间的关系信息,其中,目标线程为该线程请求调用的第一目标资源对应的资源锁的当前调用线程。基于当前处理线程与目标线程之间的关系信息,确定由该线程指向目标线程的有向线段为有向图中的有向边,利用该有向边表征出当前处理线程与目标线程之间的关系信息,即当前处理线程等待调用目标线程当前调用的目标资源。
在确定出多个节点及对应的有向边之后,便可以基于设定的多个节点与有向边,及其之间的相关关系,绘制多个线程之间的有向图。
在本公开的另一实施例中,在基于多个线程分别对应的资源调用信息,绘制多个所述线程之间的有向图之后,还包括:
在预设的有向图更新事件被触发后,更新所述有向图;
其中,所述有向图更新事件包括:线程和/或线程的资源调用信息发生改变。
具体的,所述有向图更新事件为线程发生改变时,所述在预设的有向图更新事件被触发后,更新所述有向图,包括:
当取消和/或关闭线程时,删除所述有向图中的与所述线程对应的节点;
当创建线程时,添加所述有向图中的与所述线程对应的节点。
示例性的,在当任一线程退出所述目标程序或任一线程停止运行时,删除所述有向图中与该线程对应的节点。对应的,在当任一线程加入所述目标程序时,添加所述有向图中与该线程对应的节点。在发生上述任一种情况时,有向图更新事件被触发,更新有向图。
本另一实施例中,当所述有向图更新事件为线程的资源调用信息发生改变时,所述在预设的有向图更新事件被触发后,更新所述有向图,包括:
所述线程释放当前调用资源的资源锁;
所述线程请求调用第二目标资源,并且所述线程对所述第二目标资源调用失败。
示例性的,若线程的调用的资源发生改变或不调用资源了,或是当前处理资源想要调用资源的当前调用的目标线程发生改变时,则可以改变或删除对应的有向边。当一线程由等待调用一资源转变为等待调用另一资源时,可以更改对应有向边的方向。当一线程想要调用一资源且调用失败时,在有向图中添加对应的有向边。在发生上述任一种情况时,有向图更新事件被触发,更新有向图。
三:在上述S103中,在获取有向图之后,便可以基于该有向图确定目标程序是否发生死锁。
具体的,基于所述有向图,确定所述有向图中是否存在由所述节点、以及所述有向边构成的有向环。若存在,则确定所述目标程序存在线程死锁。若多个节点、以及有向边并未构成封闭的有向环,则目标程序不存在线程死锁。
参加图2c,图2c为本公开实施例所提供的有向图构建流程的示意图之三。
如图2c所示,可以发现在该有向图中,包括一封闭的有向环。由此可以判定,在该有向环中的三个节点彼此之间构成了一个死资源调用的循环。
示例性的,分别用A、B、C表示有向环中的三个节点,可以发现A等待B调用的资源、B等待C调用的资源、C又等待A调用的资源。在等待资源的过程中,已经调用的资源不会释放,而是会在调用所有需求资源,执行对应的处理任务后,才会释放调用的资源,因此三个节点彼此之间都无法获取自己想要调用的资源,因此形成死循环,即发生了程序死锁。
通常检查死锁的方式为:应用程序的主线程失去响应达到预设的时长,且在预设时长后应用程序崩溃,那么认为此时程序发生了线程死锁。这种检测方式的误判率较高,且无法检测到无主线程参与线程死锁问题。但是在本公开实施例中,可以通过检测有向图的状态信息,判断程序是否发生死锁。由于以往的方法中只能通过主线程失去响应或是崩溃才能判断死锁,其判断方法通常为经验方法,可以会造成判断结果不准确的情况。本公开实施例里,不限定于是主线程发生死锁的情况,其他副线程发生死锁也可以被检测到。
具体的,检测程序死锁的方法包括:周期性地检测有向图的状态信息、或是按照预设的时间点检测有向图的状态信息。
示例性的,可以设定一个周期为30分钟、1个小时或是其他基于实际情况确定的周期时间,并按照该周期,检测有向图的状态信息。还可以设定时间点为9:00am、15:00pm或是其他依据经验易发生程序死锁的时间点,检测有向图的状态信息。
在本公开的另一实施例中,在确定程序发生死锁后,还可以基于该有向图,确定出有向环中多个节点对应的多个线程为发生死锁的目标线程,以方便后续针对目标线程进行处理,以解决程序死锁问题。
在本公开的另一实施例中,在确定存在线程死锁之后,其具体的解决方法包括:
释放多个所述目标线程中的第一目标线程当前调用的目标资源;其中,所述目标资源为多个所述目标线程中的第二目标线程请求调用的所述第一目标资源。
示例性的,如图2c所示,更改有向环中至少一个线程的当前调用资源,便可以删除掉或更改有向环中的至少一条有向边,由此,便可以打破当前的死循环状态,进而解决了程序死锁问题。
具体的,当程序出现死锁的时候,可以获得构成有向环的所有节点所对应的线程,对于每个发生死锁的线程,可以抓取线程的调用栈信息,并上传至服务端,通过这些信息,开发人员可以方便地了解到,哪些函数调用路径导致了最终的程序死锁,从而更改对应的函数调用路径,以解决程序死锁问题。因此,本公开实施例可以为开发人员修复相关问题提供清晰的数据支持。
本公开实施例通过获取目标程序的多个线程中每个线程的资源调用信息;其中,每个线程的资源调用信息包括:与每个线程对应的目标线程;目标线程为每个线程请求调用的第一目标资源对应的资源锁的当前调用线程;基于多个线程分别对应的资源调用信息,绘制多个线程之间的有向图;其中,有向图包括由多个线程分别构成的多个节点,以及从每个线程指向对应目标线程的有向边;基于有向图,确定目标程序的死锁检测结果,从而能够根据生成的有向图,更加快速地检测出程序是否发生死锁,提高对于程序检测的效率与准确率。
进一步的,通过绘制的有向图,可以快速确定程序中发生死锁的线程,从而可以通过调整对应线程的调用函数解决程序死锁的问题,提高了解决程序死锁问题的效率。
本领域技术人员可以理解,在具体实施方式的上述方法中,各步骤的撰写顺序并不意味着严格的执行顺序而对实施过程构成任何限定,各步骤的具体执行顺序应当以其功能和可能的内在逻辑确定。
基于同一发明构思,本公开实施例中还提供了与上述实施例提供的程序死锁的检测方法对应的程序死锁的检测装置,由于本公开实施例中的装置解决问题的原理与本公开上述实施例的程序死锁的检测方法相似,因此装置的实施可以参见方法的实施,重复之处不再赘述。
参照图3、图4所示,图3为本公开实施例所提供的一种程序死锁的检测装置的示意图,图4为本公开实施例所提供的另一种程序死锁的检测装置的示意图。所述检测装置包括:获取模块310、绘制模块320以及第一确定模块330,其中:
所述获取模块310,用于获取目标程序各线程的资源调用信息;其中,所述线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及所述目标调用资源对应资源锁的目标线程;
所述绘制模块320,用于基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图;其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;
所述第一确定模块330,用于基于所述有向图,确定所述目标程序的死锁检测结果。
本公开实施例基于程序中各线程的资源调用状态及目标调用资源,生成有向图,并根据生成的有向图,更加快速地检测出程序是否发生死锁,提高对于程序检测的效率与准确率。
在一种可能的实施方式中,如图4所示,所述检测装置还包括:生成模块340;
所述生成模块340,用于基基于多个处于被调用状态的资源锁、所述资源锁对应的资源、以及调用所述资源锁的目标线程,生成资源调用记录。
所述获取模块310具体用于:基于各线程对应的资源调用记录,确定是否存在与所述目标调用资源对应的资源锁;若所述资源调用记录中存在与所述目标调用资源对应的资源锁,基于与所述目标调用资源对应资源锁的当前调用线程,确定各的资源调用信息。
在一种可能的实施方式中,所述绘制模块320具体用于:生成所述目标程序中各个线程分别对应的节点;针对每个节点,根据所述每个节点对应的线程持有的当前调用资源,在资源调用记录中添加所述当前调用资源的资源锁被所述每个节点拥有的记录;确定所述资源调用记录中,是否存在所述每个节点的目标调用资源的资源锁;在存在的情况下,生成从所述每个节点到所述目标节点的有向边。
在一种可能的实施方式中,所述第一确定模块330具体用于:基于所述有向图,确定所述有向图中是否存在由所述节点、以及所述有向边构成的有向环;若存在,则确定所述目标程序存在线程死锁。
在一种可能的实施方式中,所述获取模块310还用于:周期性地获取目标程序的多个线程中每个线程的资源调用信息;或者,在预设的程序死锁检测事件被触发后,获取目标程序的多个线程中每个线程的资源调用信息。
在一种可能的实施方式中,所述程序死锁检测事件包括下述至少一种:所述多个线程中的任一线程请求调用第一目标资源;所述多个线程中的任一线程对所述第一目标资源调用失败。
在一种可能的实施方式中,所述检测装置还包括:更新模块350;
所述更新模块350,用于所述更新模块,用于在预设的有向图更新事件被触发后,更新所述有向图;其中,所述有向图更新事件包括:线程和/或线程的资源调用信息发生改变。
在一种可能的实施方式中,所述更新模块350具体用于:当取消和/或关闭线程时,删除所述有向图中的与所述线程对应的节点;当创建线程时,添加所述有向图中的与所述线程对应的节点。
在一种可能的实施方式中,所述更新模块350还用于:所述线程释放当前调用资源的资源锁;所述线程请求调用第二目标资源,并且所述线程对所述第二目标资源调用失败。
在一种可能的实施方式中,所述检测装置还包括:第二确定模块360;
第二确定模块360,用于基于由所述节点、以及所述有向边构成的有向环,确定与所述有向环中多个节点对应的多个线程为发生死锁的目标线程。
在一种可能的实施方式中,所述检测装置还包括:释放模块370;
所述释放模块370,用于释放多个所述目标线程中的第一目标线程当前调用的目标资源;其中,所述目标资源为多个所述目标线程中的第二目标线程请求调用的所述第一目标资源。
本公开实施例还提供了一种计算机设备10,如图5所示,为本公开实施例提供的计算机设备10结构示意图,包括:
处理器11和存储器12;所述存储器12存储有所述处理器11可执行的机器可读指令,当计算机设备运行时,所述机器可读指令被所述处理器执行以实现下述步骤:
获取目标程序各线程的资源调用信息;其中,所述线程的资源调用信息包括:各线程的当前调用资源、目标调用资源以及所述目标调用资源对应资源锁的目标线程;
基于各所述线程的资源调用信息,绘制多个所述线程之间的有向图;其中,所述有向图包括表征线程的多个节点,以及表征基于资源锁建立的线程之间有向关系的有向边;
基于所述有向图,确定所述目标程序的死锁检测结果。
上述指令的具体执行过程可以参考本公开实施例中所述的程序死锁的检测方法的步骤,此处不再赘述。
本公开实施例还提供一种计算机可读存储介质,该计算机可读存储介质上存储有计算机程序,该计算机程序被处理器运行时执行上述方法实施例中所述的程序死锁的检测方法的步骤。
本公开实施例所提供的程序死锁的检测方法的计算机程序产品,包括存储了程序代码的计算机可读存储介质,所述程序代码包括的指令可用于执行上述方法实施例中所述的程序死锁的检测方法的步骤,具体可参见上述方法实施例,在此不再赘述。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的系统和装置的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。在本公开所提供的几个实施例中,应该理解到,所揭露的系统、装置和方法,可以通过其它的方式实现。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,又例如,多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些通信接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本公开各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。
所述功能如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个处理器可执行的非易失的计算机可读取存储介质中。基于这样的理解,本公开的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本公开各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(Read-OnlyMemory,ROM)、随机存取存储器(Random Access Memory,RAM)、磁碟或者光盘等各种可以存储程序代码的介质。
最后应说明的是:以上所述实施例,仅为本公开的具体实施方式,用以说明本公开的技术方案,而非对其限制,本公开的保护范围并不局限于此,尽管参照前述实施例对本公开进行了详细的说明,本领域的普通技术人员应当理解:任何熟悉本技术领域的技术人员在本公开揭露的技术范围内,其依然可以对前述实施例所记载的技术方案进行修改或可轻易想到变化,或者对其中部分技术特征进行等同替换;而这些修改、变化或者替换,并不使相应技术方案的本质脱离本公开实施例技术方案的精神和范围,都应涵盖在本公开的保护范围之内。因此,本公开的保护范围应所述以权利要求的保护范围为准。