CN111767159A - 一种基于协程的异步***调用*** - Google Patents
一种基于协程的异步***调用*** Download PDFInfo
- Publication number
- CN111767159A CN111767159A CN202010589213.8A CN202010589213A CN111767159A CN 111767159 A CN111767159 A CN 111767159A CN 202010589213 A CN202010589213 A CN 202010589213A CN 111767159 A CN111767159 A CN 111767159A
- Authority
- CN
- China
- Prior art keywords
- coroutine
- queue
- call
- module
- system call
- 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
- 230000000977 initiatory effect Effects 0.000 claims abstract description 7
- 230000006870 function Effects 0.000 claims description 27
- 238000012545 processing Methods 0.000 claims description 9
- 230000007958 sleep Effects 0.000 claims description 7
- 230000000903 blocking effect Effects 0.000 claims description 6
- 238000013479 data entry Methods 0.000 claims description 6
- 230000002618 waking effect Effects 0.000 claims description 6
- 238000012546 transfer Methods 0.000 claims description 3
- 238000000034 method Methods 0.000 description 13
- 230000008569 process Effects 0.000 description 9
- 238000012986 modification Methods 0.000 description 8
- 230000004048 modification Effects 0.000 description 8
- 238000010586 diagram Methods 0.000 description 3
- 238000013461 design Methods 0.000 description 2
- 230000007246 mechanism Effects 0.000 description 2
- 230000001360 synchronised effect Effects 0.000 description 2
- 238000012360 testing method Methods 0.000 description 2
- 238000007792 addition Methods 0.000 description 1
- 230000005540 biological transmission Effects 0.000 description 1
- 230000008859 change Effects 0.000 description 1
- 238000012938 design process Methods 0.000 description 1
- 230000007717 exclusion Effects 0.000 description 1
- 238000002474 experimental method Methods 0.000 description 1
- 239000004744 fabric Substances 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 239000003999 initiator Substances 0.000 description 1
- 238000012544 monitoring process Methods 0.000 description 1
- 238000013486 operation strategy Methods 0.000 description 1
- 238000002360 preparation method Methods 0.000 description 1
- 238000011160 research Methods 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F9/00—Arrangements for program control, e.g. control units
- G06F9/06—Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
- G06F9/46—Multiprogramming arrangements
- G06F9/54—Interprogram communication
- G06F9/547—Remote procedure calls [RPC]; Web services
Landscapes
- Engineering & Computer Science (AREA)
- Software Systems (AREA)
- Theoretical Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Telephonic Communication Services (AREA)
Abstract
本发明公开了一种基于协程的异步***调用***,包括记录模块、执行模块、返回模块,所述记录模块与执行模块之间设有调用队列,所述执行模块、返回模块之间设有返回队列;所述记录模块用于接收协程发起的***调用请求,记录***调用请求中包含的***调用参数与协程信息,并将***调用参数与协程信息保存到调用对列中,同时暂停发起***调用的协程,然后判断是否开始执行***调用;所述执行模块用于采用辅助线程执行调用队列传来的***调用,***调用执行后将***调用返回值和协程信息存入返回队列;所述返回模块用于从返回队列中读取***调用返回值并根据协程信息将协程添加到运行队列以恢复协程运行。以解决基于协程的***调用的异步执行问题。
Description
技术领域
本发明属于操作***领域,具体涉及一种基于协程的异步***调用***。
背景技术
***调用作为应用程序与操作***的接口,是操作***向应用程序提供服务的主要方式。常见的操作***提供了几百种不同的***调用,它们提供了进程管理、内存管理、文件读写、网络管理等程序运行所必须的功能。
虽然现代处理器提供了加速***调用执行的各种功能,但***调用的开销仍然不可忽略。对于数据库、网络服务器等需要进行大量***调用的程序,***调用的运行效率对计算机***的性能有明显的影响。操作***内核通过***调用向用户态应用程序提供服务,因此***调用的开销影响了应用程序的运行速度。为了保证内核的安全性,执行***调用前需要进行许多检查与状态切换,这些操作影响了***调用的运行速度。执行***调用也会影响应用程序的局部性,进一步降低程序的运行速度。
为了提高***调用的执行效率、降低***调用对程序性能的影响,研究者们提出并实现了异步***调用机制。与异步IO类似,异步***调用的发起者不会被阻塞。***调用的执行由专用的线程进行,因此可以通过批处理等方式提高执行效率。然而目前针对异步***调用设计的应用程序较少,为了兼容现有程序,现有技术方案在C语言运行库中实现了用户态调度器,通过暂停线程运行模拟传统的同步***调用。目前研究者们通过用户态的线程调度器实现与现有编程接口的兼容,发起***调用的线程会被暂停运行,等到***调用执行结束后恢复运行。
现有的异步***调用研究以C语言常用的NPTL线程库((Native POSIX ThreadingLibrary))为基础,但此NPTL线程库并不具备用户态调度的能力。因此必须对原有线程库进行较大幅度的修改才能使用异步***调用。不同研究者实现的异步***调用可能因对运行库的修改不同造成性能差异,难以统一对比。如可以将一对一的线程库修改为一对多的线程库,正在运行的线程发起***调用时被暂停并切换至其他线程运行。还可以通过增加额外的***调用的方式增加内核对异步***调用的支持。但是这些现有技术在应用场景中会存在下面这些问题:
问题一:不支持协程调度。NPTL线程库本身没有提供协程功能,也没有为协程增加创建、管理协程的编程接口。
问题二:不支持2.6以上版本的Linux内核。通过增加新的***调用使内核支持异步***调用,新增加的***调用号与2.6以上版本的Linux内核冲突。
随着近年来协程编程的广泛应用,越来越多的应用程序使用协程技术提供更高的并发。Go语言是提供了协程机制的应用较广的编程语言之一,急需一种利用Go语言调度器内部的函数实现了对异步***的调用。
发明内容
本发明的目的是提供一种基于协程的异步***调用***,以解决在基于协程的编程语言中,***调用的异步执行问题。
为实现上述发明目的,本发明提供的技术方案为:
一种基于协程的异步***调用***,包括记录模块、执行模块、返回模块,所述记录模块与执行模块之间设有调用队列,所述执行模块、返回模块之间设有返回队列;
所述记录模块用于接收协程发起的***调用请求,记录***调用请求中包含的***调用参数与协程信息,并将***调用参数与协程信息保存到调用对列中,同时暂停发起***调用的协程,然后判断是否开始执行***调用;
所述执行模块用于采用辅助线程执行调用队列传来的***调用,***调用执行后将***调用返回值和协程信息存入返回队列;
所述返回模块用于从返回队列中读取***调用返回值并根据协程信息将协程添加到运行队列以恢复协程运行。
与现有技术相比,本发明至少包括以下优点:
实施例提供的基于协程的异步***调用***通过记录模块、执行模块、返回模块的相互配合实现了异步***调用的功能。异步***调用可以批量处理多个***调用,提升程序的性能。实验表明本***可以提高60%的内核性能从而带来13%的整体性能提升。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图做简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动前提下,还可以根据这些附图获得其他附图。
图1是本发明实施例提供的基于协程的异步***调用***的结构示意图;
图2是本发明实施例提供的无锁队列的结构示意图;
图3是本发明实施例提供的记录模型的工作流程图;
图4是本发明实施例提供的辅助线程的工作流程图。
具体实施方式
为使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例对本发明进行进一步的详细说明。应当理解,此处所描述的具体实施方式仅仅用以解释本发明,并不限定本发明的保护范围。
实施例提供的基于协程的异步***调用***。本***需要满足兼容性、性能的要求并尽量减少对原有Go语言运行时以及Linux操作***内核的影响。兼容性方面,本***的设计目的是在不改用户代码的***调用接口前提下实现基于Go协程的异步***调用,通过修改其实现方式完成异步***调用所需的记录、执行与返回等功能。
性能方面,本***需要支持多核处理器并行执行***调用。由于Go语言的调度器会尽量占用所有可用的物理并行度,因此本***在设计时需要考虑执行***调用对原有调度算法的影响。本***应当能够根据当前负载及时调整运行策略,在充分利用计算机性能的同时减少因线程数量过多所产生的调度开销。
本***中涉及到操作***内核的部分包括***调用执行线程的申请以及修改内核代码的方式。实际执行***调用的线程可以由内核中的内核线程实现,也可以在运行库中添加额外的线程进行处理。由于内核线程的使用受到诸多限制,并且用户态程序难以对其进行控制,因此本***选择在用户态申请新的线程,这种方式对内核是透明的,无需对其调度代码进行任何修改。原有的Go语言调度器也通过类似的方式实现***调用,因此这种实现对Go语言调度器的影响也较小。
对内核的修改可以通过直接修改内核源码或添加内核模块的方式实现。在本实施例中,本***只添加了一行源码以导出***调用表。除导出***调用表外,本***的所需的所有内核态功能均以内核模块的形式实现。使用时只需根据***中运行的内核版本编译内核模块。
如图1所示,该基于协程的异步***调用***包括记录模块、执行模块、返回模块。记录模块与执行模块之间的队列称为调用队列,执行模块与返回模块之间的队列称为返回队列。该异步***调用***基于Go语言设计。下面针对每一部分进行详细介绍。
本***中使用队列进行模块间的通信,并且需要跨越内核态与用户态。因此队列的性能对异步***调用的运行至关重要。所述调用队列和返回队列采用无锁队列,所述无锁队列采用原子操作实现多线程环境下调用队列和返回队列中数据的同步进行。
本***中的调用队列和返回队列与Go语言调度器中有局部与全局运行队列不同,会涉及到操作***内核,因此本***中根据需要重新实现了高性能的无锁队列。无锁队列通过原子操作以解决同步问题。常用的原子操作包括读取变量、增加变量的值、比较并交换等。比较并交换操作需要三个参数:原子变量的地址、旧值与新值。该操作首先将原子变量中的值与旧值进行比较,如果不同直接返回false,如果相同则将其替换为新值并返回true,整个过程对调用者来说是原子的。利用这种操作,使用者可以先读取某个变量的值作为旧值,计算好新值后尝试进行比较并交换操作。操作成功结束说明在运行过程中没有与其他线程的竞争,可以继续执行后续操作。如果操作失败则说明在计算新值时其他线程完成了对此变量的操作,因此需要重新读取、计算并尝试修改该变量。
原子操作的原子性由处理器提供保障,因此原子操作一般由处理器指令集提供,需要使用汇编语言进行操作。编程语言中一般通过函数的形式对汇编指令进行包装,因此相同的原子操作可能在不同的编程语言中有不同的名称。由于本***中无锁队列的实现涉及到Linux内核与Go语言,因此需要首先了解这两种编程环境下的原子操作函数。在Go语言中,原子操作由atomic包提供。
队列的基本操作包括入队与出队,无锁队列的实现需要保证多线程同时入队或出队时不发生冲突,并且出队操作需要在入队操作完成后进行。为了达到这样的要求,所述无锁队列设有用于入队和出队的序号和标号。对队列进行操作的线程只有成功通过原子操作对这些辅助变量进行修改后才可以开始对相应数据条目的读写操作。图2为无锁队列的数据结构。
入队序号与出队序号用于同步不同的生产者或消费者,整个队列只需要一个入队序号与一个出队序号;生产者在进行入队操作前通过原子指令获取入队序号并使其自增,成功修改入队序号说明此时没有发生入队冲突,可以继续进行入队操作;
在循环队列中,序号相差等于缓冲区长度时不同生产者会对应到相同的数据,因此入队标号与出队标号用来保护相应数据条目操作的原子性,每个数据条目对应一对入队与出队标号。
在使用者对队列进行操作的过程中,可能会***作***调度或因函数调用被Go运行时调度。由于缓冲区的长度有限,过长的队列操作时间将会导致后续需要同样数据条目的线程无法执行,一个线程的卡顿可能造成多个线程的等待。因此在进行队列操作前应当尽可能关闭各种形式的抢占调度以保证队列操作的顺利执行。
除了执行较早的线程应当尽量避免影响后续线程外,后续线程也需要及时发现并尽量处理其他线程卡顿的情况。队列操作在完成前不会修改入队与出队标记,并且正常情况下队列数据的读写速度非常快,几乎不会出现标号不符的情况,因此错误的标号可以提示正在运行的线程可能已经发生了卡顿。由于已获取入队或出队序号的线程必须完成所有的工作才不会导致进一步的卡顿,因此,针对入队和出队,在获取序号前可以读取并检查即将使用的队列条目中的标号。如果该条目的标号与序号不符,可以立即放弃执行,而当标号正确并成功修改序号时可以直接对该条目的数据进行操作,不需要额外的检查。
所述记录模块用于接收协程发起的***调用请求,记录***调用请求中包含的***调用参数与协程信息,并将***调用参数与协程信息保存到调用对列中,同时暂停发起***调用的协程,然后判断是否开始执行***调用。具体地,记录模块的流程如图3所示,包括以下步骤:
针对发起的***调用,判断协程是否锁定,在协程锁定时,执行传统***调用方式;在协程没有被锁定时,在调用队列中记录协程,暂停协程运行,修改入队标号,调度其他协程运行,等待***调用执行结束。
由于异步***调用在发起后需要调度其他协程运行,因此锁定的协程由于不会被调度不能使用异步***调用,这种情况需要特别处理。锁定功能由g结构体中的lockedg变量实现。
对于正常运行的协程而言,此时记录模块可以将相关参数放入调用队列中,然后通过gopark函数暂停协程运行让出线程。然而,此处存在一个隐蔽的同步问题。协程状态的修改位于gopark函数中,而队列状态则由记录模块修改,因此入队标号被修改后,***调用执行模块认为入队操作已完成,而实际上协程仍处于运行状态。如果执行模块与返回模块完成了对应的任务,在将协程加入返回队列时会遇到状态不一致的问题。在调度器中,对协程状态的修改由CAS原子指令完成,如果变量中的数值与期望值不一致则进行忙等。如果它们处于同一逻辑处理器中,由于Go语言的抢占式调度对不执行函数调用的忙等状态无效,此线程无法继续运行。因此,对入队标号的修改应当在修改协程状态之后,利用gopark函数提供的unlockf参数可以实现此目的。除此之外,由于对gopark的函数调用可能触发抢占式调度,在入队操作前后需要调用acquirem与releasem函数暂停抢占式调度。
在一个实施方式中,为了实现***调用的批处理以减小切换至内核的次数,所述记录模块中设有阈值,当***调用数量达到阈值时通知执行模块开始执行***调用。虽然对于操作***内核来说***调用的执行不需要协程相关的信息,但此协程信息需要传递给返回模块用于***调用完成后恢复协程的运行,因此调用队列中的条目除***调用号与参数外也包含了协程信息。
在一个实施方式中,所述记录模块在存在空闲逻辑处理器或***调用数量达到阈值两种情况下唤醒执行模块中的辅助线程来执行***调用。当存在空闲逻辑处理器时,执行模块可以利用闲置的处理器资源执行***调用。考虑到对于异步***调用而言,理想的应用场景中应当不存在空闲的逻辑处理器(否则在执行***调用时原线程只能等待),本***在设计过程中不研究此时如何控制同时运行的辅助线程数量,当存在空闲处理器时直接唤醒辅助线程执行***调用。
为了防止多个协程同时唤醒辅助线程,此处对唤醒进行加锁,记录模块在唤醒辅助线程前需要获得锁,辅助函数在唤醒后释放锁。与普通的自旋锁或互斥锁不同,未获得锁的协程不等待锁的释放而是直接跳过唤醒步骤,唤醒的判断与执行在***调用参数入队并恢复抢占式调用后立即执行;
除***调用发起时需要唤醒辅助线程外,在线程睡眠前也需要检查调用队列是否为空,如果有未执行的***调用则唤醒辅助线程。由于***调用的执行需要时间并且可能阻塞,因此在唤醒辅助线程后线程仍执行原有睡眠操作。与正常休眠时对逻辑处理器的操作类似,对调用队列的检查也在释放逻辑处理器之后进行。
所述执行模块用于采用辅助线程执行调用队列传来的***调用,***调用执行后将***调用返回值和协程信息存入返回队列。在执行模块中,由于采用队列的形式存储***调用,因此可以尽量多的执行传递来的***调用,无需关心启动阈值。***调用执行完成后执行模块将返回值与协程信息存入返回队列中。需要注意的是,由于执行不同***调用所需的时间不同,因此在多线程处理***调用时,同一协程在返回队列中的位置可能与调用队列不同。当执行模块由内核退出时,发起***调用的协程信息与返回值数据位于返回队列中。此时由于辅助线程没有获得逻辑处理器,不能将协程加入局部运行队列。如果将协程放入全局运行队列则会加剧对全局调度锁的竞争,因此执行模块不对这些协程进行处理,由协程调度器在合适的实际调用返回模块进行处理,执行模块只需要确保有正在运行的线程可以触发调度器。
执行模块中实际运行***调用的线程由调度器在用户态创建。内核模块通过设备驱动的形式为用户态提供接口,不产生新的线程,当***调用阻塞时由调度器进行处理。
其中,所述执行模块包括提供给记录模块的接口、用于执行***调用的辅助线程以及阻塞处理线程;接口函数判断需要执行***调用时会唤醒辅助线程进入内核态完成***调用,阻塞处理线程负责在阻塞发生时唤醒额外的辅助线程。
使用异步***调用的运行库在启动时建立多个辅助线程。这些线程与sysmon监控线程类似,不占用逻辑处理器。辅助线程在启动后直接进入睡眠状态,等待被唤醒。为了能够判断是否有辅助线程正在运行,***中设置了统计睡眠辅助线程数量的变量,它们在睡眠前与被唤醒后修改此变量。
图4是辅助线程的工作流程图,如图4所示,辅助线程的工作流程包括:辅助线程被唤醒,进入内核态,在调用队列不为空时,返回用户态,尝试唤醒执行线程,此时辅助线程被休眠;在在调用队列为空时,读取并执行***调用,并将***调用结果写入返回队列,然后返回用户态,尝试唤醒执行线程,此时辅助线程被休眠。
记录模块中的辅助线程在切换至内核态后,为了平摊切换开销并提高局部性,辅助线程不断处理调用队列中的***调用直到调用队列位空,不受执行模块启动阈值的影响。在处理***调用时,辅助线程首先从调用队列中取得相应的***调用号、参数与协程信息。如果调用队列为空则直接返回用户态。辅助线程在返回前不需要反复检查确认调用队列为空,此时新发起的***调用可以留在调用队列中,直到数量达到阈值后记录模块再次唤醒执行模块。
辅助线程将参数保存到合适的变量之后根据***调用号调用***调用表sys_call_table中对应位置的函数,并获得***调用返回值。随后辅助线程将返回值与对应的协程信息写入返回队列后返回用户态。
执行完已经记录的***调用并返回用户态后,由于此时已完成***调用的协程位于返回队列中,并且读取返回队列的功能位于返回模块中,受调度器控制,辅助线程需要判断是否需要唤醒线程执行这些协程。辅助线程在完成***调用后重新进入睡眠状态。
执行***调用可能导致线程阻塞,在特定情况下可能导致***运行停滞,这种现象可能发生于***调用数量低于阈值但高于逻辑处理器数量时。如果这些***调用中产生阻塞,由于数量较少,记录时不会唤醒辅助线程,而释放逻辑处理器时唤醒的辅助线程数量也不会超过逻辑处理器数量。如果除此之外没有其他线程唤醒辅助线程,程序可能因所有线程均阻塞在***调用而无法运行。为了防止这种现象的出现,本***在监控线程sysmon中增加对调用队列出队标号的检查,如果连续两次唤醒时观察到的出队标号没有变化并且小于入队标号,则认为正在执行的***调用发生了阻塞,需要唤醒辅助线程。
所述返回模块用于从返回队列中读取***调用返回值并根据协程信息将协程添加到运行队列以恢复协程运行。由于需要恢复协程的运行,返回模块的部分功能在调度函数中实现。对于调度函数来说,返回队列类似于额外的全局运行队列,调度器在寻找可用协程时需要调用返回模块对此队列进行处理。
在异步***调用中,由于发起***调用的协程不直接调用***调用指令,因此无法通过返回值的形式直接获得***调用的结果。为了解决返回值存储的问题,在异步***调用的实现中需要额外的存储空间存放返回值。所述***调用返回值的存储方式为:在记录模块中申请额外的内存空间存放返回值;或在相对于每个协程固定的位置记录返回值。
针对申请额外的内存空间存放返回值,由于Go语言在编译时会进行变量逃逸分析,禁止将指向栈的指针传递给其他函数,因此只能申请额外的堆内存。然而当用户代码的***调用数量较大时,频繁的申请与释放小块内存会对性能产生较大影响。
针对相对于每个协程固定的位置记录返回值,由于每个协程都有对应的g结构体保存其相关调度信息,因此可以在其中加入新的成员变量保存最近一次***调用的结果。由于指向协程的指针已经作为额外参数参与异步***调用的信息传递中,因此可以直接使用此指针将返回值写入协程数据结构中对应的变量。
新的可运行协程只能由已经在运行的线程放入对应逻辑处理器P的运行队列或全局队列中。由于对全局运行队列的修改需要获取全局调度锁sched.lock,可能影响***性能,因此本***选择由正在运行的线程读取返回队列并将已经完成***调用的协程放入对应逻辑处理器的运行队列中。
由于对运行队列的访问没有限制,因此调度器代码的任何部分都可以完成此工作。为了减小对调度器的整体影响,本***选择在读取本地运行队列之前处理已经完成的***调用,以便调度器无需做额外的检查即能够正常获取可执行的协程。
在另外一个实施方式中,所述异步***调用***还包括初始化模块,用于在应用程序启动时向内存管理器中申请一块共享内存用作数据传递和执行***调用。
用户态程序在使用异步***调用之前需要通过open***调用打开设备节点。内核模块执行mydev_open函数时可以认为用户态的应用程序正在初始化阶段,并且尝试使用异步***调用技术。因此内核模块需要完成对应的准备工作,此时内核模块通过kzalloc函数向内存管理器申请一块固定大小的内存用作数据传递。内存的大小不会影响异步***调用的顺利执行,但更大的内存意味着更长的队列,在负载较高时可以减小因竞争产生的性能影响。内核模块可以根据***运行状况申请合适的内存大小。
在成功申请到内存后,将其地址写入file结构体中的private_data成员中,此成员变量是Linux内核为方便设备驱动保存自己的额外信息而提供的。接下来用户态程序可以通过mmap***调用将内存映射到自己的进程地址空间中。这项工作通过调用remap_pfn_range函数实现,将private_data中的地址传递给此函数。当mmap成功返回时,用户态程序成功获得一块可用的共享内存。此时***内核与应用程序可以通过共享内存传递数据,因此对共享内存中数据结构的初始化工作可由用户态程序完成。
在实际执行***调用时,执行模块通过ioctl***调用进入内核模块中,然后通过private_data获取共享内存的地址并执行对应的***调用。***调用的结果也写回到共享内存中。
该基于协程的异步***调用***在给定的测试环境与测试程序下测试结果表明,异步***调用在合适的场景下能够带来足够抵消调度开销的性能提升,使内核态运行效率提升最多60%,程序的总运行速度提高最多13%。在实际应用中可以提高net/http包最多4.4%的性能。
以上所述的具体实施方式对本发明的技术方案和有益效果进行了详细说明,应理解的是以上所述仅为本发明的最优选实施例,并不用于限制本发明,凡在本发明的原则范围内所做的任何修改、补充和等同替换等,均应包含在本发明的保护范围之内。
Claims (9)
1.一种基于协程的异步***调用***,其特征在于,包括记录模块、执行模块、返回模块,所述记录模块与执行模块之间设有调用队列,所述执行模块、返回模块之间设有返回队列;
所述记录模块用于接收协程发起的***调用请求,记录***调用请求中包含的***调用参数与协程信息,并将***调用参数与协程信息保存到调用对列中,同时暂停发起***调用的协程,然后判断是否开始执行***调用;
所述执行模块用于采用辅助线程执行调用队列传来的***调用,***调用执行后将***调用返回值和协程信息存入返回队列;
所述返回模块用于从返回队列中读取***调用返回值并根据协程信息将协程添加到运行队列以恢复协程运行。
2.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述异步***调用***还包括初始化模块,用于在应用程序启动时向内存管理器中申请一块共享内存用作数据传递和执行***调用。
3.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述调用队列和返回队列采用无锁队列,所述无锁队列采用原子操作实现多线程环境下调用队列和返回队列中数据的同步进行。
4.如权利要求3所述的基于协程的异步***调用***,其特征在于,所述无锁队列设有用于入队和出队的序号和标号,入队序号与出队序号用于同步不同的生产者或消费者,整个队列只需要一个入队序号与一个出队序号;生产者在进行入队操作前通过原子指令获取入队序号并使其自增,成功修改入队序号说明此时没有发生入队冲突,可以继续进行入队操作;
入队标号与出队标号用来保护相应数据条目操作的原子性,每个数据条目对应一对入队与出队标号;
针对入队和出队,在获取序号前可以读取并检查即将使用的队列条目中的标号,如果该条目的标号与序号不符,可以立即放弃执行,而当标号正确并成功修改序号时直接对该条目的数据进行操作,不需要额外的检查。
5.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述记录模块中设有阈值,当***调用数量达到阈值时通知执行模块开始执行***调用。
6.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述记录模块在存在空闲逻辑处理器或***调用数量达到阈值两种情况下唤醒执行模块中的辅助线程来执行***调用;
为了防止多个协程同时唤醒辅助线程,此处对唤醒进行加锁,唤醒的判断与执行在***调用参数入队并恢复抢占式调用后立即执行;
除***调用发起时需要唤醒辅助线程外,在线程睡眠前也需要检查调用队列是否为空,如果有未执行的***调用则唤醒辅助线程;
在唤醒辅助线程后线程仍执行原有睡眠操作。
7.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述执行模块包括提供给记录模块的接口、用于执行***调用的辅助线程以及阻塞处理线程;接口函数判断需要执行***调用时会唤醒辅助线程进入内核态完成***调用,阻塞处理线程负责在阻塞发生时唤醒额外的辅助线程。
8.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述***调用返回值的存储方式为:
在记录模块中申请额外的内存空间存放返回值;或在相对于每个协程固定的位置记录返回值。
9.如权利要求1所述的基于协程的异步***调用***,其特征在于,所述异步***调用***基于Go语言设计。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010589213.8A CN111767159A (zh) | 2020-06-24 | 2020-06-24 | 一种基于协程的异步***调用*** |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202010589213.8A CN111767159A (zh) | 2020-06-24 | 2020-06-24 | 一种基于协程的异步***调用*** |
Publications (1)
Publication Number | Publication Date |
---|---|
CN111767159A true CN111767159A (zh) | 2020-10-13 |
Family
ID=72721646
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202010589213.8A Pending CN111767159A (zh) | 2020-06-24 | 2020-06-24 | 一种基于协程的异步***调用*** |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN111767159A (zh) |
Cited By (10)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112346835A (zh) * | 2020-10-22 | 2021-02-09 | 上海瀚之友信息技术服务有限公司 | 一种基于协程的调度处理方法及*** |
CN113392038A (zh) * | 2021-08-17 | 2021-09-14 | 北京鲸鲮信息***技术有限公司 | 基于Linux内核的***休眠内存管理方法及装置 |
CN113568686A (zh) * | 2020-10-30 | 2021-10-29 | 深圳市九九互动科技有限公司 | Lua语言的异步处理方法、装置、计算机设备和存储介质 |
CN114356825A (zh) * | 2021-12-17 | 2022-04-15 | 郑州信大捷安信息技术股份有限公司 | 一种基于芯片的spi双路通信方法和*** |
CN115098220A (zh) * | 2022-06-17 | 2022-09-23 | 西安电子科技大学 | 基于容器线程管理技术的大规模网络节点拟真方法 |
WO2023280097A1 (zh) * | 2021-07-08 | 2023-01-12 | 华为技术有限公司 | 一种缺页异常的处理方法及相应装置 |
CN115904542A (zh) * | 2022-12-15 | 2023-04-04 | 润芯微科技(江苏)有限公司 | 一种应用于安卓***的异步初始化任务的方法及*** |
CN116225728A (zh) * | 2023-05-09 | 2023-06-06 | 北京星辰天合科技股份有限公司 | 基于协程的任务执行方法、装置、存储介质及电子设备 |
CN116594758A (zh) * | 2023-07-18 | 2023-08-15 | 山东三未信安信息科技有限公司 | 一种密码模块调用优化***及优化方法 |
CN117270831A (zh) * | 2023-11-17 | 2023-12-22 | 天津华来科技股份有限公司 | 一种协议类同步与协程调用兼容实现方法 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104102494A (zh) * | 2014-07-31 | 2014-10-15 | 武汉邮电科学研究院 | 无线通信基站空口数据cipher加速方法 |
CN106980546A (zh) * | 2016-01-18 | 2017-07-25 | 阿里巴巴集团控股有限公司 | 一种任务异步执行方法、装置及*** |
CN108021449A (zh) * | 2017-12-01 | 2018-05-11 | 厦门安胜网络科技有限公司 | 一种协程实现方法、终端设备及存储介质 |
CN108156181A (zh) * | 2018-02-01 | 2018-06-12 | 杭州安恒信息技术股份有限公司 | 一种基于协程异步io的漏洞探测方法及其漏洞扫描*** |
-
2020
- 2020-06-24 CN CN202010589213.8A patent/CN111767159A/zh active Pending
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104102494A (zh) * | 2014-07-31 | 2014-10-15 | 武汉邮电科学研究院 | 无线通信基站空口数据cipher加速方法 |
CN106980546A (zh) * | 2016-01-18 | 2017-07-25 | 阿里巴巴集团控股有限公司 | 一种任务异步执行方法、装置及*** |
CN108021449A (zh) * | 2017-12-01 | 2018-05-11 | 厦门安胜网络科技有限公司 | 一种协程实现方法、终端设备及存储介质 |
CN108156181A (zh) * | 2018-02-01 | 2018-06-12 | 杭州安恒信息技术股份有限公司 | 一种基于协程异步io的漏洞探测方法及其漏洞扫描*** |
Non-Patent Citations (1)
Title |
---|
超级大猪: "go笔记:go语言中使用协程异步并行", pages 1 - 2, Retrieved from the Internet <URL:https://cloud.tencent.com/developer/article/1542668> * |
Cited By (18)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112346835A (zh) * | 2020-10-22 | 2021-02-09 | 上海瀚之友信息技术服务有限公司 | 一种基于协程的调度处理方法及*** |
CN112346835B (zh) * | 2020-10-22 | 2022-12-09 | 上海瀚之友信息技术服务有限公司 | 一种基于协程的调度处理方法及*** |
CN113568686B (zh) * | 2020-10-30 | 2023-11-28 | 深圳市九九互动科技有限公司 | Lua语言的异步处理方法、装置、计算机设备和存储介质 |
CN113568686A (zh) * | 2020-10-30 | 2021-10-29 | 深圳市九九互动科技有限公司 | Lua语言的异步处理方法、装置、计算机设备和存储介质 |
WO2023280097A1 (zh) * | 2021-07-08 | 2023-01-12 | 华为技术有限公司 | 一种缺页异常的处理方法及相应装置 |
CN113392038A (zh) * | 2021-08-17 | 2021-09-14 | 北京鲸鲮信息***技术有限公司 | 基于Linux内核的***休眠内存管理方法及装置 |
CN114356825A (zh) * | 2021-12-17 | 2022-04-15 | 郑州信大捷安信息技术股份有限公司 | 一种基于芯片的spi双路通信方法和*** |
CN114356825B (zh) * | 2021-12-17 | 2024-02-13 | 郑州信大捷安信息技术股份有限公司 | 一种基于芯片的spi双路通信方法和*** |
CN115098220A (zh) * | 2022-06-17 | 2022-09-23 | 西安电子科技大学 | 基于容器线程管理技术的大规模网络节点拟真方法 |
CN115098220B (zh) * | 2022-06-17 | 2024-04-16 | 西安电子科技大学 | 基于容器线程管理技术的大规模网络节点拟真方法 |
CN115904542B (zh) * | 2022-12-15 | 2024-01-30 | 润芯微科技(江苏)有限公司 | 一种应用于安卓***的异步初始化任务的方法及*** |
CN115904542A (zh) * | 2022-12-15 | 2023-04-04 | 润芯微科技(江苏)有限公司 | 一种应用于安卓***的异步初始化任务的方法及*** |
CN116225728B (zh) * | 2023-05-09 | 2023-07-14 | 北京星辰天合科技股份有限公司 | 基于协程的任务执行方法、装置、存储介质及电子设备 |
CN116225728A (zh) * | 2023-05-09 | 2023-06-06 | 北京星辰天合科技股份有限公司 | 基于协程的任务执行方法、装置、存储介质及电子设备 |
CN116594758A (zh) * | 2023-07-18 | 2023-08-15 | 山东三未信安信息科技有限公司 | 一种密码模块调用优化***及优化方法 |
CN116594758B (zh) * | 2023-07-18 | 2023-09-26 | 山东三未信安信息科技有限公司 | 一种密码模块调用优化***及优化方法 |
CN117270831A (zh) * | 2023-11-17 | 2023-12-22 | 天津华来科技股份有限公司 | 一种协议类同步与协程调用兼容实现方法 |
CN117270831B (zh) * | 2023-11-17 | 2024-02-23 | 天津华来科技股份有限公司 | 一种协议类同步与协程调用兼容实现方法 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN111767159A (zh) | 一种基于协程的异步***调用*** | |
US7962923B2 (en) | System and method for generating a lock-free dual queue | |
CN101833475B (zh) | 用于执行指令原子块的方法和装置 | |
US7650602B2 (en) | Parallel processing computer | |
JP5678135B2 (ja) | オペレーティング・システム介入なしにos隔離シーケンサー上でスレッドをスケジューリングする機構 | |
US9274859B2 (en) | Multi processor and multi thread safe message queue with hardware assistance | |
US7594234B1 (en) | Adaptive spin-then-block mutual exclusion in multi-threaded processing | |
US8473964B2 (en) | Transparent user mode scheduling on traditional threading systems | |
US6314563B1 (en) | Expedited object locking and unlocking | |
Brandenburg | Multiprocessor real-time locking protocols | |
US8321874B2 (en) | Intelligent context migration for user mode scheduling | |
US20060271932A1 (en) | Transparent support for operating system services for a sequestered sequencer | |
US20170024249A1 (en) | Parallel Execution Mechanism and Operating Method Thereof | |
US20050066149A1 (en) | Method and system for multithreaded processing using errands | |
Takada et al. | A novel approach to multiprogrammed multiprocessor synchronization for real-time kernels | |
US20050283783A1 (en) | Method for optimizing pipeline use in a multiprocessing system | |
JP7346649B2 (ja) | 同期制御システムおよび同期制御方法 | |
US9946665B2 (en) | Fetch less instruction processing (FLIP) computer architecture for central processing units (CPU) | |
Khushu et al. | Scheduling and Synchronization in Embedded Real-Time Operating Systems | |
CN115858132A (zh) | 线程调度方法、装置、芯片、电子设备及存储介质 | |
Bläse | Non-Blocking Synchronization in Operating Systems | |
AG | The Case for Migratory Priority Inheritance in Linux: Bounded Priority Inversions on Multiprocessors |
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 |