1.本技术属于计算机领域,具体涉及一种无栈协程的实现方法、装置、设备及存储介质。
背景技术:2.协程,又称为微线程,在执行的过程中,可以在中断当前的协程函数后去执行别的协程函数,再返回来继续执行该当前的协程函数。其中,协程包括无栈协程,即不使用栈和上下文切换来执行异步代码逻辑的机制。无栈协程是一种高效、简单的异步编程方式,它大大的提高了异步编程的效率,降低了异步编程的复杂度,使得代码更具有稳定性和可扩展性。但是无栈协程在协程挂起后(yield),协程函数的局部变量的内容会消失。
3.为了解决上述问题,目前,通常采用全局变量替代局部变量,但这种方法会导致协程函数不具有可重入性。因此,亟需一种新的无栈协程的实现方法。
技术实现要素:4.为了解决上述问题,即为了解决采用全局变量替代局部变量会导致协程函数不具有可重入性的问题,本技术提供了一种无栈协程的实现方法、装置、设备及存储介质。
5.第一方面,本技术提供了一种无栈协程的实现方法,包括:获取无栈协程的源文件,源文件包括协程函数;采用语法分析器,提取协程函数包括的局部变量;将局部变量封装到堆的结构体中;为结构体分配结构体指针;将局部变量替换为结构体指针,得到源文件对应的目标文件。
6.在上述无栈协程的实现方法的优选技术方案中,采用语法分析器,提取协程函数包括的局部变量,包括:采用语法分析器对源文件进行语法分析,根据协程函数的标识信息确定源文件中的协程函数;确定协程函数中的局部变量。
7.在上述无栈协程的实现方法的优选技术方案中,将局部变量封装到堆的结构体中之前,还包括:为结构体分配存储空间;基于存储空间的大小,创建结构体。
8.在上述无栈协程的实现方法的优选技术方案中,为结构体分配存储空间,包括:创建结构体的空间分配语句;根据空间分配语句,为结构体分配存储空间。
9.在上述无栈协程的实现方法的优选技术方案中,为结构体分配结构体指针,包括:创建结构体指针的获取语句;根据获取语句,为结构体分配结构体指针。
10.在上述无栈协程的实现方法的优选技术方案中,得到源文件对应的目标文件之后,还包括:确定目标文件是否符合无栈协程的使用规则,使用规则包括协程函数不允许使用局部变量;在目标文件符合使用规则的情况下,输出目标文件。
11.第二方面,本技术提供了一种无栈协程的实现装置,包括:获取模块,用于获取无栈协程的源文件,源文件包括协程函数;提取模块,用于采用语法分析器,提取协程函数包括的局部变量;封装模块,用于将局部变量封装到堆的结构体中;分配模块,用于为结构体分配结构体指针;替换模块,用于将局部变量替换为结构体指针,得到源文件对应的目标文
件。
12.第三方面,本技术提供了一种电子设备,包括:处理器,以及与处理器通信连接的存储器;存储器存储计算机执行指令;处理器执行存储器存储的计算机执行指令,以实现如第一方面的无栈协程的实现方法的技术方案。
13.第四方面,本技术提供了一种计算机可读存储介质,计算机可读存储介质中存储有计算机执行指令,计算机执行指令被处理器执行时用于实现第一方面的无栈协程的实现方法的技术方案。
14.第五方面,本技术提供了一种计算机程序产品,包括计算机程序,计算机程序被处理器执行时实现如第一方面的无栈协程的实现方法的技术方案。
15.本技术提供的无栈协程的实现方法、装置、设备及存储介质,通过采用语法分析器提取源文件中的协程函数的局部变量,然后将局部变量封装到堆的结构体中,这样就可以使用结构体指针来替换协程函数的局部变量,因此,避免了无栈协程中无法使用局部变量的问题,在保证用户可以更容易写出安全的无栈协程代码的同时,保证协程函数的可重入性,提高无栈协程的开发效率和稳定性。
附图说明
16.此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本技术的实施例,并与说明书一起用于解释本技术的原理。
17.为了更清楚地说明本技术实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
18.图1为本技术实施例提供的无栈协程的实现方法的一种应用场景示意图;
19.图2为本技术实施例提供的无栈协程的实现方法的流程图;
20.图3为本技术实施例提供的无栈协程的实现装置的结构示意图;
21.图4为本技术实施例提供的电子设备的结构示意图。
具体实施方式
22.为了使本技术领域的人员更好地理解本技术方案,下面将结合本技术实施例中的附图,对本技术实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本技术一部分的实施例,而不是全部的实施例。基于本技术中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本技术保护的范围。
23.需要说明的是,本技术的说明书和权利要求书及上述附图中的术语“第一”、“第二”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的本技术的实施例能够以除了在这里图示或描述的那些以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。
24.下面首先对本技术中涉及的名词进行解释。
25.无栈协程:是一种高效,简单的异步编程方式。它大大的提高了异步编程的效率,降低了异步编程的复杂度,使得代码更具有稳定性和可扩展性。
26.可重入性:具有可重入性的函数必须满足以下三个条件:(1)可以在执行的过程中可以被打断;(2)被打断之后,在该函数一次调用执行完之前,可以再次被调用(或进入,reentered);(3)再次调用执行完之后,被打断的上次调用可以继续恢复执行,并正确执行。
27.堆(heap):是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。
28.背景技术中提到的相关技术,至少存在以下技术问题:
29.无栈协程虽然可以提高异步编程的效率,降低异步编程的复杂度,但是无栈协程存在协程挂起后(yield),局部变量的内容消失的问题。业务逻辑必须使用yield之前的上下文信息,若无法使用局部变量,则需要开发人员修改设计,将上下文信息保存到外部结构中,并通过参数传递的方式传递进来,而这种方式增加了开发人员的负担,并且并非所有的场景都可以使用;并且开发人员极易误使用局部变量,而局部变量又无法使用,因此,会导致代码出现漏洞(bug)。
30.为了避免这种问题,一种相关技术,比如腾讯libco协程,通过采用有栈协程的实现方式,没有局部变量引用的问题,但是有栈协程需要提前分配好栈的大小,内存消耗是无栈协程的几百倍,存在内存资源消耗大的问题,不适用与嵌入式系统;另一种相关技术,比如contikios,通过采用全局变量替代局部变量的实现方式,但是这种做法,使得协程函数不具有可重入性,同时也增加了内存消耗。
31.针对上述的问题,本技术提出一种无栈协程的实现方法,通过提取源文件中的协程函数的局部变量,然后将局部变量封装到堆的结构体中,这样就可以使用结构体指针来替换协程函数的局部变量,因此,可以避免无栈协程中无法使用局部变量的问题,在保证用户可以更容易写出安全的无栈协程代码的同时,保证了协程函数的可重入性。
32.在一种可能的实施方式中,可以在一种应用场景中应用该实施例提供的无栈协程的实现方法。图1为本技术实施例提供的无栈协程的实现方法的一种应用场景示意图,如图1所示,将无栈协程的源文件输入至语法分析器中,通过语法分析器中的识别模块识别出源文件中的协程函数,并通过语法分析器中的提取模块提取出协程函数中的局部变量,然后通过封装模块将提取出来的局部变量封装为堆的结构体,从而可以通过替换模块使用结构体指针替换掉源文件中的所有局部变量,这样就可以得到符合无栈协程的使用规则的目标文件。
33.在上述场景中,由于将源文件中的协程函数的局部变量提取出来,且将局部变量封装到堆的结构体中,并使用结构体指针来替换协程函数的局部变量,因此,可以避免无栈协程中无法使用局部变量的问题,保证了协程函数的可重入性。
34.结合上述场景,下面通过几个具体实施例对本技术提供的无栈协程的实现方法的技术方案进行详细说明。
35.本技术实施例提供一种无栈协程的实现方法。图2为本技术实施例提供的无栈协程的实现方法的流程图,如图2所示,该无栈协程的实现方法包括以下步骤:
36.s201:获取无栈协程的源文件。
37.在该步骤中,无栈协程的源文件可以为c语言的代码文件。用户可以将源文件输入到电子设备中,该电子设备可以为设置有语法分析器的设备。
38.s202:采用语法分析器,提取协程函数包括的局部变量。
39.在该步骤中,语法分析器可以为python语法分析器,该语法分析器可以为用于对c语言的代码文件进行语法分析的脚本。
40.可选地,在获取到无栈协程的源文件之后,可以采用语法分析器对源文件进行语法分析,确定出源文件中包括的协程函数,然后再提取出协程函数包括的局部变量。
41.可选地,源文件中够可以包括协程函数,也可以包括除协程函数之外的其他函数,由于需要对协程函数中的局部变量进行提取,因此,需要首先将源文件中的协程函数识别出来,仅对协程函数进行局部变量的提取处理,而对源文件中的其他函数,则不进行任何处理。
42.s203:将局部变量封装到堆的结构体中。
43.在该步骤中,在通过语法分析器将协程函数中的局部变量提取出来之后,可以将局部变量进行封装,也即,采用堆的结构体的方式将提取的局部变量定义为堆的结构体类型,因此,得到的堆的结构体中包含了所有的局部变量的信息,该信息可以为局部变量的值,这样就可以通过该堆的结构体获取到所有的局部变量的信息。
44.s204:为结构体分配结构体指针。
45.在该步骤中,由于在使用结构体时,需要先获取结构体指针,这样才可以通过结构体指针,访问结构体变量信息,进而访问到局部变量的信息,因此,需要为堆的结构体分配结构体指针。
46.s205:将局部变量替换为结构体指针,得到源文件对应的目标文件。
47.在该步骤中,每个协程函数都可以携带参数,该参数可以用来保存结构体指针,因此,可以将源文件的协程函数中包括的局部变量替换为结构体指针,这样得到的目标文件中既包括协程函数,又可以不包括局部变量,从而,目标文件中的协程函数每次在工作时,都可以通过该参数获取到结构体指针,进而获取到局部变量的信息,也就避免了在协程挂起后,局部变量的内容消息的问题。
48.本技术实施例提供的无栈协程的实现方法,通过提取源文件中的协程函数的局部变量,然后将局部变量封装到堆的结构体中,这样就可以使用结构体指针来替换协程函数的局部变量,因此,可以避免无栈协程中无法使用局部变量的问题,在保证用户可以更容易写出安全的无栈协程代码的同时,保证了协程函数的可重入性。
49.在一种可能的实施方式中,采用语法分析器,提取协程函数包括的局部变量,包括:采用语法分析器对源文件进行语法分析,根据协程函数的标识信息确定源文件中的协程函数;确定协程函数中的局部变量。
50.在该方案中,协程函数的标识信息可以为协程函数声明宏,每个协程函数都携带有协程函数声明宏,这样语法分析器在对源文件进行语法分析时,就可以通过协程函数声明宏来识别出源文件中的协程函数,然后语法分析器就可以对源文件中的协程函数包括的局部变量进行提取。
51.在上述方案中,由于源文件中除了包括协程函数之外,还可以包括其他函数,通过协程函数声明宏确定源文件中的协程函数,可以提高对源文件中包括的协程函数进行识别
的准确率,从而提高对协程函数的局部变量进行提取的成功率,因此,可以避免无栈协程中无法使用局部变量的问题,并且保证了用户可以更容易写出安全的无栈协程代码,也提高了无栈协程的开发效率和稳定性。
52.在一种可能的实施方式中,将局部变量封装到堆的结构体中之前,还包括:为结构体分配存储空间;基于存储空间的大小,创建结构体。
53.在该方案中,由于结构体在进行初始化时,是没有存储空间的,因此,需要先为结构体分配存储空间,在为结构体分配了存储空间之后,局部变量的声明(比如类型、值等)才可以在结构体中进行存储,这样就可以通过结构体获取到局部变量的信息,因此,可以避免无栈协程中无法使用局部变量的问题。
54.在上述方案中,所有的局部变量可以封装在一个结构体中,
55.在一种可能的实施方式中,为结构体分配存储空间,包括:创建结构体的空间分配语句;根据空间分配语句,为结构体分配存储空间。
56.在该方案中,在为结构体分配存储空间时,需要写空间分配语句,可选地,可以为写用于空间分配的代码,这样才可以申请到结构体的存储空间,以便于将局部变量的声明存储在结构体中,从而可以通过结构体获取到局部变量的信息,因此,可以避免无栈协程中无法使用局部变量的问题。
57.在一种可能的实施方式中,为结构体分配结构体指针,包括:创建结构体指针的获取语句;根据获取语句,为结构体分配结构体指针。
58.在该方案中,在为结构体分配结构体指针时,可以创建结构体指针的获取语句,可选地,该获取语句可以为用于获取结构体指针的代码,这样才可以获取到结构体的结构体指针,从而可以通过结构体指针,访问结构体变量信息,进而访问到局部变量的信息,因此,可以避免无栈协程中无法使用局部变量的问题。
59.在一种可能的实施方式中,得到源文件对应的目标文件之后,还包括:确定目标文件是否符合无栈协程的使用规则,使用规则包括协程函数不允许使用局部变量;在目标文件符合使用规则的情况下,输出目标文件。
60.在该方案中,无栈协程的使用规则即为协程函数中不允许使用局部变量,因此,在得到目标文件之后,理想情况下,目标文件是符合无栈协程的使用规则的。但不排除会出现操作失误或者代码出错等意外情况,导致目标文件不符合无栈协程的使用规则,因此,在得到目标文件之后,可以先对目标文件进行核查,确定目标文件中协程函数的局部变量的位置是否全部替换为结构体变量访问的方式。若局部变量的位置全部替换为结构体变量访问的方式,则该目标文件即为符合无栈协程的使用规则的文件;若有局部变量的位置未被替换为结构体变量访问的方式,则需要确定是否未提取出全部的局部变量,或者确定是否在替换时漏掉了某个局部变量,或者出现的其他情况,然后在处理之后,使目标文件符合无栈协程的使用规则即可,提高了将局部变量替换为结构体变量的准确率。
61.在上述方案中,由于源文件需要生成目标文件才可以进行编译使用,但是源文件中还包括不是协程函数的其他函数,会导致目标文件不可以直接使用,因此,增加了对目标文件记性编译的复杂度,所以,存在对源文件进行二次处理的问题,也即,需要识别出源文件中的协程函数,从而可以修改编译工具链,也即,在生成目标文件的过程中,就采用语法分析器通过协程函数声明宏来识别出源文件中的协程函数,然后直接确定出所有的协程函
数,并将所有的协程函数的局部变量替换为结构体指针,这样最后得到的目标文件就符合无栈协程的使用规则,从而目标文件就可以直接进行编译使用。
62.在上述方案中,目标文件可以为c语言的代码文件。通过将源文件转换为符合无栈协程的使用规则的目标文件,可以避免无栈协程中无法使用局部变量的问题,在保证用户可以更容易写出安全的无栈协程代码的同时,可以保证协程函数的可重入性,提高无栈协程的开发效率和稳定性。
63.本技术实施例提供的无栈协程的实现方法,通过使用python语法分析器提取出协程函数中定义的局部变量,并将其转换为结构体指针的方式,避免了无栈协程中无法使用局部变量的问题,使得用户(开发者)可以更容易写出安全的无栈协程代码,用户不需要关心局部变量的问题,可以很大程度降低用户对无栈协程的心智负担,提高开发效率和稳定性。
64.从总体上来说,本技术提供的技术方案,是一种既可以实现避免无栈协程中无法使用局部变量的问题,又可以保证协程函数的可重入性,还可以提高无栈协程的开发效率、稳定性和安全性的技术方案。
65.本技术还提供一种无栈协程的实现装置。图3为本技术实施例提供的无栈协程的实现装置的结构示意图,如图3所示,该无栈协程的实现装置300可以包括:
66.获取模块301,用于获取无栈协程的源文件,源文件包括协程函数;
67.提取模块302,用于采用语法分析器,提取协程函数包括的局部变量;
68.封装模块303,用于将局部变量封装到堆的结构体中;
69.分配模块304,用于为结构体分配结构体指针;
70.替换模块305,用于将局部变量替换为结构体指针,得到源文件对应的目标文件。
71.可选地,提取模块302在采用语法分析器,提取协程函数包括的局部变量时,具体用于:采用语法分析器对源文件进行语法分析,根据协程函数的标识信息确定源文件中的协程函数;确定协程函数中的局部变量。
72.可选地,该无栈协程的实现装置300还可以包括创建模块(未示出),该创建模块可以具体用于:在将局部变量封装到堆的结构体中之前,为结构体分配存储空间;基于存储空间的大小,创建结构体。
73.可选地,创建模块在为结构体分配存储空间时,可以具体用于:创建结构体的空间分配语句;根据空间分配语句,为结构体分配存储空间。
74.可选地,分配模块304在为结构体分配结构体指针时,可以具体用于:创建结构体指针的获取语句;根据获取语句,为结构体分配结构体指针。
75.可选地,该无栈协程的实现装置300还可以包括输出模块(未示出),该输出模块可以具体用于:在得到源文件对应的目标文件之后,确定目标文件是否符合无栈协程的使用规则,使用规则包括协程函数不允许使用局部变量;在目标文件符合使用规则的情况下,输出目标文件。
76.该无栈协程的实现装置用于执行前述无栈协程的实现方法实施例提供的技术方案,其实现原理和技术效果与前述方法实施例中类似,在此不再赘述。
77.本技术实施例还提供了一种电子设备。图4为本技术实施例提供的电子设备的结构示意图,如图4所示,电子设备400可以包括处理组件401,其进一步包括一个或多个处理
器,以及由存储器402所代表的存储器资源,用于存储可由处理组件401执行的计算机执行指令,例如应用程序。存储器402中存储的应用程序可以包括一个或一个以上的每一个对应于一组指令的模块。此外,处理组件401被配置为执行计算机执行指令,以执行上述无栈协程的实现方法的实施例。
78.电子设备400还可以包括一个电源组件403,电源组件403被配置为执行电子设备400的电源管理,一个有线或无线网络接口404被配置为将电子设备400连接到网络,和一个输入输出(i/o)接口405。电子设备400可以操作基于存储在存储器402的操作系统,例如windows servertm,mac os xtm,unixtm,linuxtm,freebsdtm或类似。
79.存储器可以是,但不限于,随机存取存储器(random access memory,简称:ram),只读存储器(read only memory,简称:rom),可编程只读存储器(programmable read-only memory,简称:prom),可擦除只读存储器(erasable programmable read-only memory,简称:eprom),电可擦除只读存储器(electric erasable programmable read-only memory,简称:eeprom)等。其中,存储器用于存储程序,处理器在接收到执行指令后,执行程序。进一步地,上述存储器内的软件程序以及模块还可包括操作系统,其可包括各种用于管理系统任务(例如内存管理、存储设备控制、电源管理等)的软件组件和/或驱动,并可与各种硬件或软件组件相互通信,从而提供其他软件组件的运行环境。
80.处理器可以是一种集成电路芯片,具有信号的处理能力。上述的处理器可以是通用处理器,包括中央处理器(central processing unit,简称:cpu)、网络处理器(network processor,简称:np)等。可以实现或者执行本技术实施例中的公开的各方法、步骤及逻辑框图。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
81.本技术实施例还提供一种计算机可读存储介质,计算机可读存储介质中存储有计算机执行指令,计算机执行指令被处理器执行时用于实现前述方法实施例中提供的无栈协程的实现方法的技术方案。
82.本技术实施例还提供一种计算机程序产品,包括计算机程序,计算机程序被处理器执行时用于实现前述方法实施例中提供的无栈协程的实现方法的技术方案。
83.本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成。前述的程序可以存储于一计算机可读取存储介质中。该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:rom、ram、磁碟或者光盘等各种可以存储程序代码的介质。
84.以上所述仅是本技术的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本技术原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本技术的保护范围。