Runtime virtualization method and apparatus, runtime virtual machine system

By building a dynamic runtime library to simulate threaded coroutines, the compatibility issues between coroutines and threads are solved, and the concurrency performance improvement of the application and the optimization of system resource management are achieved.

CN119166268BActive Publication Date: 2025-06-17XIAN TONGXING HENGYAO INFORMATION TECHNOLOGY CO LTD

Patent Information

Application Number
CN202310942815.0
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2023-07-28
Publication Date
2025-06-17
Estimated Expiration
2043-07-28

AI Technical Summary

Technical Problem

The existing coroutine library fails to effectively solve the compatibility issues between coroutines and threads, resulting in limited performance improvement in high-concurrency applications.

Method used

By building a dynamic runtime library, using coroutine methods to simulate threads in the native runtime library, generate a runtime virtualization environment, and receive application task requests under this environment, and use coroutine scheduling threads to schedule coroutines to complete tasks.

Benefits of technology

Without modifying or recompiling the application, the concurrency performance of the application is improved, the thread resource occupancy rate in the system is effectively controlled, the system resource consumption and resource scheduling pressure is reduced, and the overall throughput and availability of the system is improved.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN119166268B_ABST
    Figure CN119166268B_ABST
Patent Text Reader

Abstract

The present disclosure provides a runtime virtualization method and apparatus. A specific implementation of the method includes: constructing a dynamic runtime library based on the native runtime library of an application, where the dynamic runtime library simulates threads implemented in the native runtime library in a coroutine manner; loading the dynamic runtime library when starting the application to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, where the coroutine scheduling thread is used to schedule coroutines, and the runtime virtualization environment is an environment after replacing the native runtime library with a generated runtime environment; receiving a task request of the application in the runtime virtualization environment; and scheduling coroutines using the coroutine scheduling thread based on the task request and the dynamic runtime library so that the coroutines complete the tasks corresponding to the task request. This implementation improves the concurrency performance of the application, reduces resource consumption and resource scheduling pressure without making any modifications or recompiling to the application in the target operating system.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present disclosure relates to the field of computer technologies, and particularly to a runtime virtualization method and apparatus, a runtime virtual machine system, an electronic device, and a computer-readable medium. Background Art

[0002] A coroutine is a lightweight parallel subroutine that multiplexes the runtime slices of the host thread by time sharing. Since the coroutine multiplexes the context of the host thread, the process of swapping in and out the coroutine is only equivalent to a function call, saving the additional context switching cost. Compared with ordinary threads, the cost of swapping in and out a coroutine is generally about one order of magnitude lower.

[0003] As a runtime virtualization solution, although the coroutine library reduces the overhead of high-concurrency applications and improves performance by utilizing the lightweight switching of coroutines, its implementation often only non-blockingly asynchronously simulates the IO library functions for coroutines, and does not properly solve the compatibility problem between coroutines and threads. Summary of the Invention

[0004] Embodiments of the present disclosure provide a runtime virtualization method and apparatus, a runtime virtual machine system, an electronic device, and a computer-readable medium.

[0005] In a first aspect, an embodiment of the present disclosure provides a runtime virtualization method, the method including: constructing a dynamic runtime library based on the native runtime library of an application, where the dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner; loading the dynamic runtime library when starting the application to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, where the coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is an environment after replacing the runtime environment generated by the native runtime library; receiving a task request of the application in the runtime virtualization environment; and scheduling the coroutine by using the coroutine scheduling thread based on the task request and the dynamic runtime library, so that the coroutine completes the task corresponding to the task request.

[0006] In some embodiments, scheduling the coroutine by using the coroutine scheduling thread based on the task request and the dynamic runtime library, so that the coroutine completes the task corresponding to the task request includes: creating at least one coroutine based on the task request and the dynamic runtime library; and sending the at least one coroutine to the coroutine scheduling thread to schedule the at least one coroutine by using the coroutine scheduling thread.

[0007] In some embodiments, the above-mentioned coroutine scheduling thread includes: a scheduler and a lock-free queue for placing at least one coroutine. Scheduling at least one coroutine by the coroutine scheduling thread includes: the scheduler obtaining a coroutine in a ready state from the lock-free queue among at least one coroutine; synchronizing the coroutine context of the coroutine with the thread context in the thread control block; after the coroutine actively yields, the scheduler obtaining the next coroutine in a ready state from the lock-free queue and synchronizing the coroutine context of the next coroutine with the thread context in the thread control block; after the next coroutine actively yields, the scheduler continues to obtain coroutines from the lock-free queue and synchronize the thread control block until there are no coroutines in the lock-free queue.

[0008] In some embodiments, the above-mentioned method further includes: receiving a native request of an application program, creating at least one thread based on the native request and the native runtime library in the dynamic runtime library, and executing a task corresponding to the native request through the at least one thread.

[0009] In some embodiments, building a dynamic runtime library based on the native runtime library of the application program includes: using a hook mechanism to build a thread library function hook related to a first library function, where the first library function is a library function in the native runtime library for creating a thread and obtaining a thread descriptor; in the thread library function hook, replacing the thread descriptor with a coroutine context structure, and marking the currently running thread or coroutine through a global variable with thread-local constraints, and managing the thread-local storage information in the coroutine context structure through a synchronization management module, where the synchronization management module is used to synchronize the thread-local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.

[0010] In some embodiments, building a dynamic runtime library based on the native runtime library of the application program further includes: using a hook mechanism to build a lock library function hook related to a second library function, where the second library function is a library function in the native runtime library related to locks, condition variables, and semaphores respectively; in the lock library function hook, judging the currently running entity through a global variable, and giving a corresponding lock mechanism for the currently running entity based on the currently running entity.

[0011] In some embodiments, building a dynamic runtime library based on the native runtime library of the application program further includes: using a hook mechanism to build a switching library function hook related to a third library function, where the third library function is a library function in the native runtime library that can cause a thread switching or suspension operation; the switching library function hook is used to replace the thread switching or suspension mechanism with a coroutine switching or suspension mechanism.

[0012] Second aspect, embodiments of the present disclosure provide a runtime virtualization device, the device includes: a construction unit configured to construct a dynamic runtime library based on the native runtime library of the application, the dynamic runtime library simulating the threads implemented in the native runtime library in a coroutine manner; a generation unit configured to load the dynamic runtime library when starting the application, generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, the coroutine scheduling thread being used to schedule at least one coroutine, the runtime virtualization environment being the environment after replacing the generated runtime environment of the native runtime library; a task receiving unit configured to receive a task request of the application in the runtime virtualization environment; a coroutine scheduling unit configured to schedule the coroutine based on the task request and the dynamic runtime library by using the coroutine scheduling thread, so that the coroutine completes the task corresponding to the task request.

[0013] In some embodiments, the above-mentioned scheduling unit is configured to: create at least one coroutine based on the task request and the dynamic runtime library; send at least one coroutine to the coroutine scheduling thread to schedule at least one coroutine by using the coroutine scheduling thread.

[0014] In some embodiments, the above-mentioned coroutine scheduling thread includes: a scheduler and a lock-free queue for placing at least one coroutine, and the scheduling unit is further configured to: the scheduler obtains the coroutine in the ready state from the at least one coroutine in the lock-free queue; synchronize the coroutine context of the coroutine with the thread context in the thread control block; after the coroutine actively yields, the scheduler obtains the next coroutine in the ready state from the lock-free queue and synchronizes the coroutine context of the next coroutine with the thread context in the thread control block; after the next coroutine actively yields, the scheduler continues to obtain coroutines from the lock-free queue and synchronize the thread control block until there are no coroutines in the lock-free queue.

[0015] In some embodiments, the above-mentioned device further includes: a native receiving unit configured to receive a native request of the application; a thread scheduling unit configured to create at least one thread based on the native request and the dynamic runtime library, and execute the task corresponding to the native request through the at least one thread.

[0016] In some embodiments, the above-mentioned construction unit is configured to: construct a thread library function hook related to the first library function by using the hook mechanism, the first library function being a library function for creating a thread and obtaining a thread descriptor in the native runtime library; in the thread library function hook, replace the thread descriptor with a coroutine context structure, and mark the current running thread or coroutine through a global variable with thread local constraints, and manage the thread local storage information in the coroutine context structure through a synchronization management module, the synchronization management module being used to synchronize the thread local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.

[0017] In some embodiments, the above-mentioned construction unit is configured to: use a hook mechanism to construct a lock library function hook related to a second library function, where the second library function is a library function related to locks in the native runtime library; in the lock library function hook, judge the currently running entity through a global variable with thread-local constraints, and based on the currently running entity, provide a corresponding lock mechanism for the currently running entity.

[0018] In some embodiments, the above-mentioned construction unit is configured to: use a hook mechanism to construct a switching library function hook related to a third library function, where the third library function is a library function in the native runtime library that can cause thread switching or suspension operations; the switching library function hook is used to replace the thread switching or suspension mechanism with a coroutine switching or suspension mechanism.

[0019] In a third aspect, an embodiment of the present disclosure provides a runtime virtual machine system, which includes: a coroutine scheduling thread, a main thread, an event-driven (EPOLL) thread, and an asynchronous input / output (AIO) and timer thread running in a runtime virtualization environment, where the runtime virtualization environment is generated by loading a dynamic runtime library, and the dynamic runtime library is constructed based on the native runtime library of the application program, and the dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner; the coroutine scheduling thread is used to schedule at least one coroutine to enable the coroutine to complete the task requests of the application program; the main thread is created when the application program starts; the event-driven thread is used to maintain the status of file handles, and when the read or write buffer is ready and there are read / write tasks blocked on the file handle, wake up the corresponding coroutine; the asynchronous input / output and timer thread obtains the results of asynchronous input / output tasks and wakes up the coroutines waiting for IO; when the system call times out and returns, pop up the timed-out tasks and wake up; when the system calls the results of asynchronous IO tasks, wake up the coroutines waiting for IO.

[0020] In a fourth aspect, an embodiment of the present disclosure provides an electronic device, which includes: one or more processors; a storage device on which one or more programs are stored; when the one or more programs are executed by the one or more processors, the one or more processors implement the method described in any one of the embodiments in the first aspect.

[0021] In a fifth aspect, an embodiment of the present disclosure provides a computer-readable medium, on which a computer program is stored, and when the program is executed by a processor, it implements the method described in any one of the embodiments in the first aspect.

[0022] The runtime virtualization method and apparatus provided by embodiments of the present disclosure first construct a dynamic runtime library based on the native runtime library of an application; secondly, load the dynamic runtime library when starting the application to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, where the coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is the environment after replacing the runtime environment generated by the native runtime library; thirdly, receive a task request of the application in the runtime virtualization environment; finally, based on the task request and the dynamic runtime library, use the coroutine scheduling thread to schedule the coroutine so that the coroutine completes the task corresponding to the task request. Thus, the present disclosure generates a runtime virtualization environment through the dynamic runtime library, transparently replaces the runtime environment of the application, and improves the concurrency performance of the application without any modification or recompilation of the application; the coroutine with thread capabilities generated by the dynamic runtime library supports lightweight coroutine scheduling, which can effectively control the occupancy rate of thread resources in the system, reduce system resource consumption and resource scheduling pressure, and thus improve the overall throughput and availability of the system. BRIEF DESCRIPTION OF THE DRAWINGS

[0023] Other features, objects, and advantages of the present disclosure will become more apparent by reading the detailed description of the non-limiting embodiments with reference to the following drawings:

[0024] Figure 1 is a flowchart of an embodiment of the runtime virtualization method according to the present disclosure;

[0025] Figure 2 is a schematic structural diagram of an embodiment of the runtime virtualization apparatus according to the present disclosure;

[0026] Figure 3 is a schematic structural diagram of a runtime virtual machine system according to the present disclosure;

[0027] Figure 4 is another schematic structural diagram of a runtime virtual machine system according to the present disclosure;

[0028] Figure 5 is a schematic structural diagram of an electronic device suitable for implementing embodiments of the present disclosure. DETAILED DESCRIPTION OF THE EMBODIMENTS

[0029] The present disclosure will be further described in detail below with reference to the drawings and embodiments. It can be understood that the specific embodiments described herein are only used to explain the related invention and are not intended to limit the invention. Additionally, it should be noted that for the sake of description, only parts related to the relevant invention are shown in the drawings.

[0030] It should be noted that, without conflict, the embodiments in the present disclosure and the features in the embodiments may be combined with each other. The following will describe the present disclosure in detail with reference to the drawings and in conjunction with the embodiments.

[0031] A runtime virtual machine system is often used to provide cross-platform support or provide a virtualized runtime environment, and dynamic library injection is a technical solution that can be used to implement a runtime virtual machine. Inject a dynamic library into an application, and this dynamic library overwrites the functions in the original application and the functions in the dynamic libraries linked by the original application with its function hooks.

[0032] Among the currently disclosed such solutions, libhybris based on Android bionic is a typical example. Android dynamic libraries are all compiled based on bionic. However, there is no bionic runtime environment in the GNU version of Linux distributions. In order to run Android dynamic libraries in a GNU distribution system, a runtime virtual machine compatible with glibc is required, that is, the libhybris library loads Android dynamic libraries based on the glibc system and uses the hook functions in libhybris to overwrite the library functions of bionic; and the hook functions of libhybris simulate the similar implementations corresponding to the bionic library functions by dynamically loading and calling the corresponding functions in glibc. That is to say, libhybris solves the compatibility problem of two C runtime libraries and realizes the runtime environment for running Android programs across platforms.

[0033] Libhybris can be regarded as a complete runtime virtual machine, which realizes a complete set of bionic simulation runtime environments in a GNU environment. In addition, many coroutine libraries also implement partial C runtime library hooks to solve the asynchronous problems of coroutine lock waiting and IO waiting, such as the open-source libco library, libgo library, and so on.

[0034] A complete coroutine library will hook those IO library functions that need to wait in a blocking manner (IO is very likely not to be completed immediately, so the corresponding library function calls need to wait for the IO operation to end before returning), as well as the locks dedicated to coroutines.

[0035] Why do coroutines need to hook IO library functions? Because the running of a coroutine depends on its host thread. Once this coroutine attempts to call a library function that may cause a blocking wait, then during the waiting process, the host thread will be suspended until the function returns. During this suspension stage, the host thread cannot execute any other code.

[0036] Coroutines are scheduled by time-sharing and multiplexing the time slices of the host thread, and their performance depends on the effective utilization rate of the time slices of the host thread. Once the host thread is suspended by a coroutine and other coroutines cannot be called during this period, the time slices during the suspension phase will be wasted, resulting in a decline in overall performance. Suspending the host thread by a coroutine not only affects performance but also causes a scheduling "deadlock" problem. Imagine a situation where all host threads are in a long-term suspension waiting state, and at this time a new coroutine hopes to be scheduled for execution. Then the system falls into a state similar to "deadlock", and the new coroutine can only wait for one of the host threads to return from the suspended library function. And once there is a "timeout" mechanism for the new coroutine, an extreme situation where the new coroutine always times out and fails may occur. In addition, if coroutines use "thread locks", it will exacerbate the "scheduling deadlock". For example, if coroutine 1 is swapped out (yield) while holding thread lock A, and the coroutine 2 swapped in (resume) by the current host thread at this time also wants to lock thread lock A, then coroutine 2 will suspend the host thread waiting for the release of thread lock A; but since the host thread is suspended, there will never be an opportunity to swap in coroutine 1 that can unlock thread lock A, resulting in a complete deadlock.

[0037] A complete coroutine library needs to simulate all library functions that may cause blocking waits (including IO waits and lock waits) with non-blocking asynchronous calls. That is to say, when a coroutine may be in an IO wait or a lock wait, it should use the swap-out (yield) mechanism to return to the host thread so that the host thread can continue to call other coroutines; subsequently, when the coroutine swapped out due to waiting can continue to execute (that is, the resource it is waiting for is ready - such as IO completion, unlocking, etc.), it can be scheduled (resume) again during the subsequent idle time slice of the host thread. Providing an IO library function hook for the C runtime library in the coroutine library is a relatively perfect solution. For example, when an application using the coroutine library calls the recv function to receive a network packet, it will actually call the recv function hooked by the coroutine library; if the network packet has not arrived at this time, this hook function will swap out with the yield mechanism; subsequently, when the network packet arrives, the previously swapped-out coroutine will be swapped in (resume) again at an appropriate time and continue to execute from the position where it was swapped out before, complete the reception of the network packet and return from the hook function. In this way, when developing an application, the functions in the C runtime library can be directly used; until runtime, the native library functions are dynamically replaced with coroutine version hook functions through dynamic library injection. In this way, through the above solution, the coroutineization of the application is achieved almost "transparently".

[0038] An application may have both coroutines and threads at the same time. The waiting of a coroutine lock is simulated by the yield behavior, while the waiting of a thread lock requires actually suspending the thread. The behavior patterns of the two are often incompatible. Therefore, if an application using a coroutine library wants to introduce a lock mechanism, it needs to carefully choose whether to use a coroutine lock or a thread lock, and thus cannot achieve complete "transparency" for the application.

[0039] Furthermore, existing coroutine libraries generally do not properly handle the cross-coroutine security issue of thread-local storage. That is to say, coroutines scheduled by the same host thread will share the thread-local storage of the host thread, which causes the coroutines to "pollute" each other's thread-local storage, unable to achieve cross-coroutine secure access to the thread-local storage, and thus not having the same capabilities as threads.

[0040] In summary, most coroutine libraries are not a complete runtime virtual machine, but only use the dynamic library injection method to hook some library functions of the C runtime library to solve the concurrent performance problem and the scheduling deadlock problem. That is to say, a coroutine library is generally just a runtime virtualization solution for threads (using coroutines to simulate threads), and does not completely simulate the underlying interfaces in the C runtime library.

[0041] To better understand the traditional technology, some terms are introduced below:

[0042] Shared library: Also known as "dynamic link library", it is a way to implement shared functions or objects in an operating system. Compiled functions are stored in the shared library, and an application can dynamically load such library files and reference the corresponding functions by function names; the same shared library can be loaded by different applications.

[0043] C runtime library: A general term for a class of dynamic link libraries that provides encapsulation for system calls and various operating system management interfaces, and provides a C-language-based programming interface for the interaction between an application and the operating system during runtime. An application can be directly built based on the C runtime library or run on a runtime virtual machine built based on the C runtime library.

[0044] Runtime virtual machine: A general term for a program and library that provides development interfaces and a runtime environment for other applications. Such programs are generally developed based on the C runtime library and aim to provide a cross-platform program runtime environment (e.g., the "JAVA virtual machine", which shields the differences between the C runtime libraries of different operating systems and provides system-independent development interfaces and runtime environments); or provide a virtualized runtime environment for the target operating system (e.g., "containers", which can run multiple container systems simultaneously in a host system). Compared with a "virtual machine", a runtime virtual machine does not fully simulate a virtual host but only provides a runtime environment, thus being lighter.

[0045] Dynamic library injection: Retroactively modifying a third-party application to make it execute the injected code is called "code injection"; and dynamic library injection is a way to achieve code injection. So-called "dynamic library injection" is to inject the code in the dynamic library into the target application by loading the dynamic library into the application, so that this part of the code is executed by the application, or dynamically replace the original code in the application with the injected code (the latter is also called code "hook" - hook).

[0046] Co-routine: Also known as "fiber thread" or "micro thread", a computer component that generates non-preemptive multitasking subroutines. Co-routines generally attach to a certain thread, allowing different subroutine entry points to pause or start at the same position; simply put, a co-routine is a function that can pause and start. Different co-routines can be regarded as different functions and are called and executed by the host thread; during execution, a co-routine can return to the position where the host thread called the co-routine by actively yielding (i.e., "yield"); and when the host thread calls the co-routine function again (i.e., "resume"), the co-routine will continue to execute from the previous yield point position (i.e., the so-called "same position" in the previous text).

[0047] Thread local storage (TLS): Also known as thread local storage, it is a solution to thread safety issues in specific scenarios. Simply put, it is a variable with a process-wide scope. When it has a thread local constraint, this variable can have different values in different threads (i.e., thread local values). TLS is divided into two types and three situations according to the implementation method. The first type is a variable declared with a thread local constraint during coding, for example:

[0048] static __thread int global_tls_value = 0;

[0049] The above variable declaration represents a global integer variable with an initial value of 0. This variable can be accessed in all threads of the program where it is located. However, changes made to this variable by different threads are only visible to the current thread. This type of TLS variable (referred to as "dtv" in glibc) can have its position in the program's data segment and its initial value determined during the compilation phase. Therefore, its relevant information and initial value are stored in the compiled target program, and when the program is loaded, its position in the thread-local context is locked. There is also another situation. When the program loads a dynamic library during runtime, if the dynamic library also contains TLS variables, the positions of these TLS variables in the thread-local context need to be determined dynamically when the dynamic library is loaded. In addition to the TLS variables declared during coding, there is a second type, namely dynamically created TLS. Similar APIs are provided in different operating systems to support this type of TLS.

[0050] The present disclosure provides a runtime virtualization method that can flexibly use coroutines to simulate and schedule threads, improving concurrency performance. As Figure 1 , FIG. 100 shows a flow of an embodiment of the runtime virtualization method according to the present disclosure. The runtime virtualization method includes the following steps:

[0051] Step 101, construct a dynamic runtime library based on the native runtime library of the application.

[0052] In this embodiment, the native runtime library is a runtime library that supports the operation of the application, provides a programming interface for the interaction between the application and the operating system during runtime, and the native runtime library can be built based on the C language.

[0053] In this embodiment, the dynamic runtime library is a type of dynamic library. The compiled functions are stored in the dynamic runtime library, and the dynamic runtime library provides an API (Application Program Interface) interface that supports task requests to the application. This API interface is a library function of the dynamic runtime library. When the dynamic runtime library is not loaded, the application needs to call the API of the native runtime library (the library function of the native runtime library). After the dynamic runtime library is loaded, the API of the native runtime library is hijacked by the library function of the dynamic runtime library. Therefore, when the application has a task requirement, it actually calls the API of the dynamic runtime library and sends a task request to the API of the dynamic runtime library. Based on the native runtime library, by hooking the library functions related to thread scheduling in the native runtime library, a dynamic runtime library can be obtained, and after the dynamic runtime library is loaded, it can have a scheduling ability equivalent to that of a thread.

[0054] In this embodiment, the C runtime library can be fully hooked to obtain a dynamic runtime library. The dynamic runtime library provides a runtime virtualization environment, and the application runs in this runtime virtualization environment, achieving the purpose of simulating the threads implemented in the native runtime library in the form of coroutines, and scheduling coroutines through coroutine scheduling and scheduling threads.

[0055] Step 102: When the application is started, load the dynamic runtime library to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment.

[0056] In this embodiment, the coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is the environment after replacing the runtime environment generated by the native runtime library.

[0057] In this embodiment, loading the dynamic runtime library means that when the operating system starts the application, the dynamic runtime library is dynamically injected into the application. The runtime injection of the dynamic runtime library is to load a certain dynamic library and run the initialization code in this dynamic library before the operating system starts an application and loads the program into memory. Through this program loading method, the pre-loaded dynamic library has the opportunity to build a runtime virtualization environment in advance. This runtime virtualization environment can replace the runtime environment generated by the native runtime library. In this runtime virtualization environment, the application or the operating system can call the functions in the dynamic runtime library in real time. In this embodiment, after the application is started, the coroutine scheduling thread can be started accordingly.

[0058] In this embodiment, a runtime virtualization environment can be implemented by loading a dynamic runtime library without making any modifications to the application (neither the application code needs to be modified nor the application needs to be recompiled). At this time, the application runs in the runtime virtualization environment without any awareness (in this runtime virtualization environment, when the application needs to call the library functions of the native runtime library, the library functions of the dynamic runtime library are actually called). The runtime virtualization method provided by the present disclosure not only improves performance and reduces resource consumption, but also enables applications developed based on native runtime libraries to obtain performance improvement and resource consumption reduction without modification and without awareness.

[0059] In this embodiment, a coroutine scheduling thread is a thread that schedules coroutines. There can be one or more coroutine scheduling threads, and the number of coroutine scheduling threads can be determined based on the number of cores. For example, for an operating system with 64 cores, there are 64 coroutine scheduling threads.

[0060] Optionally, the coroutines in this embodiment can be comparable to threads in terms of capabilities, and the coroutines can also fully simulate the behavior of threads. Therefore, a coroutine scheduling thread can also be considered a thread that schedules threads.

[0061] Step 103, in the runtime virtualization environment, receive a task request from the application.

[0062] In this embodiment, the task corresponding to the task request of the application can be one or multiple. For each different task, the application can create corresponding threads or coroutines by calling functions in the dynamic runtime library. Among them, each thread executes a corresponding task, and each coroutine executes a corresponding task.

[0063] In this embodiment, the application is a program developed based on a native runtime library. Without modification and without awareness of the application, the application runs in the runtime virtualization environment without awareness, and the application calls the library functions in the dynamic runtime library to implement corresponding functions.

[0064] Step 104, based on the task request and the dynamic runtime library, use the coroutine scheduling thread to schedule the coroutine so that the coroutine completes the task corresponding to the task request.

[0065] In this embodiment, the task request is a request for processing a task through a coroutine. After obtaining the task request of the application program, the execution entity calls a function in the dynamic runtime library to generate at least one coroutine corresponding to the task request, or calls a function in the dynamic runtime library to collect existing coroutines corresponding to the task request. Different coroutine scheduling threads are distinguished based on the coroutine context of the coroutine. The execution entity sends the coroutine to the corresponding coroutine scheduling thread, and the coroutine scheduling thread schedules the obtained at least one coroutine to make each coroutine work and complete the task corresponding to the task request.

[0066] The runtime virtualization method provided by the embodiment of the present disclosure. First, based on the native runtime library of the application program, a dynamic runtime library is constructed. Secondly, when the application program is started, the dynamic runtime library is loaded to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment. The coroutine scheduling thread is used to schedule at least one coroutine. The runtime virtualization environment is the environment after replacing the generated runtime environment of the native runtime library. Thirdly, in the runtime virtualization environment, a task request of the application program is received. Finally, based on the task request and the dynamic runtime library, the coroutine scheduling thread is used to schedule the coroutine so that the coroutine completes the task corresponding to the task request. Thus, the present disclosure generates a runtime virtualization environment through the dynamic runtime library, transparently replaces the runtime environment of the application program, and improves the concurrency performance of the application program without making any modifications or recompilations to the application program. The coroutine with thread capabilities generated by the dynamic runtime library supports lightweight coroutine scheduling, can effectively control the occupancy rate of thread resources in the system, reduce system resource consumption and resource scheduling pressure, and thus improve the overall throughput and availability of the system.

[0067] In some optional implementation manners of this embodiment, based on the task request and the dynamic runtime library, using the coroutine scheduling thread to schedule the coroutine so that the coroutine completes the task corresponding to the task request includes: creating at least one coroutine based on the task request and the dynamic runtime library; sending the at least one coroutine to the coroutine scheduling thread to use the coroutine scheduling thread to schedule the at least one coroutine.

[0068] In this embodiment, creating at least one coroutine based on the task request and the dynamic runtime library includes: determining a task based on the task request; scheduling a thread library function hook in the dynamic runtime library, and creating a coroutine corresponding to the task through the thread library function hook. The thread library function hook is obtained by hooking a first library function, and the first library function is a library function in the native runtime library for creating a thread and obtaining a thread descriptor.

[0069] The method for scheduling a coroutine by using a coroutine scheduling thread provided by this embodiment. First, constructing a coroutine corresponding to the task request in the way of constructing a thread can make the obtained coroutine have the same capabilities as a thread. Secondly, using the coroutine scheduling thread to schedule the constructed coroutine improves the task execution efficiency.

[0070] In some alternative implementation manners of this embodiment, the coroutine scheduling thread includes: a scheduler and a lock-free queue for placing at least one coroutine. Scheduling at least one coroutine by using the coroutine scheduling thread includes: the scheduler obtaining a coroutine in a ready state from the lock-free queue; synchronizing the coroutine context of the coroutine with the thread context in the thread control block; after the coroutine actively yields, the scheduler obtaining the next coroutine in a ready state from the lock-free queue and synchronizing the coroutine context of the next coroutine with the thread context in the thread control block; after the next coroutine actively yields, the scheduler continuing to obtain coroutines from the lock-free queue and synchronizing the thread control block until there are no coroutines in the lock-free queue.

[0071] In this embodiment, the thread control block is a data structure of a thread in the native runtime library, called "Thread Control Block" (abbreviated as TCB), that is, the context structure of the thread. The dtv and specific array are the data structures for storing TLS data in the TCB. The dtv: is used to store the TLS variables defined in the encoding stage. This data will increment as the application loads new dynamic libraries because there may also be TLS variables in the dynamic libraries.

[0072] Specific: Dynamically created TLS (where the library functions for creating and deleting TLS keys are: pthread_key_create and pthread_key_delete respectively; and the library functions for reading and modifying TLS values are: pthread_getspecific and pthread_setspecific respectively). This type of TLS is maintained by an array of pointers (specific arrays), so there is an upper limit on the number (Linux supports creating up to 1024 dynamic TLS at most).

[0073] In this embodiment, the scheduler will perform incremental synchronization of TLS data between the TCB and the coroutine context.

[0074] The coroutine scheduling thread provided in this embodiment has a scheduler and a lock-free queue, and realizes the tasks of the task requests of the application program by the scheduler scheduling the coroutines in the lock-free queue. And since the coroutine scheduling thread will not be suspended by any operation, the reliability of task execution is ensured.

[0075] In another embodiment of the present disclosure, the above method further includes: receiving a native request of the application program; creating at least one thread based on the native request and the native runtime library in the dynamic runtime library, and executing the task corresponding to the native request through the at least one thread.

[0076] In this embodiment, the native request is a request for an application program to call a library function in the native runtime library to generate a thread. Creating at least one thread based on the native request and the native runtime library in the dynamic runtime library includes: determining a thread creation task based on the native request; and invoking a function for creating a native thread from the native runtime library based on the thread creation task to create at least one thread for executing the task corresponding to the native request.

[0077] The runtime virtualization method provided in this embodiment retains the capabilities of the native runtime library through the dynamic runtime library. When the application program needs to schedule the thread construction function of the native runtime library, at least one thread is created, and the task corresponding to the native request is executed by the at least one thread, improving the diversity of request execution and ensuring the compatibility effect between threads and coroutines.

[0078] In view of the problem that the traditional coroutine library does not implement the coroutine simulation of thread local storage and it is unsafe to use thread local storage in coroutines, in some disclosed alternative implementation manners, constructing the dynamic runtime library based on the native runtime library of the application program includes:

[0079] Adopting a hook mechanism to construct a thread library function hook related to the first library function, where the first library function is a library function for creating a thread and obtaining a thread descriptor in the native runtime library; in the thread library function hook, replacing the thread descriptor with a coroutine context structure, and marking the currently running thread or coroutine through a global variable with thread local constraints, and managing the thread local storage information in the coroutine context structure through a synchronization management module, where the synchronization management module is used to synchronize the thread local storage of the coroutine when the coroutine schedules the thread to schedule the coroutine.

[0080] The coroutine context structure (hereinafter referred to as the COCTX structure) is a structure for placing the coroutine context (hereinafter referred to as the COCTX), used to maintain the context of the coroutine, and its role is similar to that of a thread descriptor (or thread handle). To provide compatibility with thread behavior, it is necessary to hook the library functions for creating a thread and obtaining a thread descriptor in the native runtime library, and replace the thread descriptor with the COCTX. Taking Linux as an example, its thread descriptor is called "TCB", and its implementation is a structure named "pthread". The calls for creating a thread and obtaining a thread descriptor in Linux are respectively:

[0081] pthread_create: Creates a thread and returns a thread descriptor, and the value of this thread descriptor is the address of the TCB structure. In this embodiment, the hook of the thread creation function is replaced by returning a pointer to the COCTX.

[0082] pthread_self: Obtains the descriptor of the current thread, which is also replaced by a pointer to the COCTX.

[0083] In this embodiment, a global TLS variable (a global variable with thread-local constraints) can be used to obtain the context of the current coroutine, and its declaration is as follows:

[0084] extern __thread COCTX* _current_coctx;

[0085] In this embodiment, COCTX has the following four types:

[0086] Coroutine COCTX: corresponding to an actual coroutine;

[0087] Global COCTX: The _current_coctx of the main thread will be set to global COCTX, and this COCTX will be created when the dynamic library is just loaded;

[0088] Scheduler COCTX: Each coroutine scheduling thread (i.e., the thread running the coroutine) will have a default COCTX. When no coroutine is in the ready state or in the intermediate state of coroutine switching, the _current_coctx of the current thread will be set to scheduler COCTX;

[0089] Single COCTX: When creating a native system thread, a virtual COCTX will be created for it.

[0090] As above, the hook function of pthread_self actually returns the value of _current_coctx. In the program, by judging the type of the current COCTX, it is possible to know which type of thread and which running state the current is in.

[0091] In this embodiment, the content stored in the COCTX structure includes: the coroutine stack and TLS. The dynamic library allocates an independent stack for each coroutine, so it can completely simulate the behavior of a thread (including the memory size allocated in the stack and the call stack depth).

[0092] If the coroutine cannot completely simulate the TLS mechanism of the thread, it will cause the coroutine to be unable to safely access variables with TLS constraints. In this embodiment, the encapsulation of TLS management is realized through a synchronization management module (hereinafter referred to as co_tls), and the capabilities provided by co_tls are crucial for "transparent" simulation of threads. Taking Linux as an example, the following two types of TLS are stored in its TCB: dtv and specific.

[0093] Support of co_tls in the present disclosure for specific: In co_tls, a data structure similar to specific arrays in TCB needs to be maintained. When a newly created coroutine is first swapped in for execution, the specific in the TCB of its affiliated scheduling thread will be copied. In addition, it is necessary to hook the library functions that manage specific. The library functions of Linux were listed above, and there are similar functions in Windows, namely: TlsAlloc, TlsFree, TlsGetValue, and TlsSetValue.

[0094] Support of co_tls in the present disclosure for dtv: Similarly, when a newly created coroutine is first scheduled for execution, the dtv in the TCB also needs to be copied. However, different from specific, the content of specific in co_tls does not need to be synchronized with the TCB anymore; but due to the possible dynamic loading of other dynamic libraries during runtime, the dtv in co_tls needs to be incrementally synchronized with the dtv in the TCB. An incremental backup of the TCB dtv is stored in the scheduler COCTX to describe the incremental part of the dtv generated each time a dynamic library is loaded. At the same time, it is necessary to hook the library function call for loading the dynamic library (this library function is called dlopen in Linux, and corresponds to LoadLibrary in Windows). Taking Linux as an example, a data structure called "link_map" describes all dynamic library information. Combining link_map and the dtv incremental backup, the difference between the current coroutine and the dtv increment can be parsed out. For the merging of the dtv increment, a "lazy" synchronization scheme is adopted, that is, it is judged whether the dtv needs to be synchronized when the coroutine is about to be swapped in. If dlopen is called in a certain coroutine, it is necessary to identify _current_coctx as the coroutine type in the hook of dlopen and immediately synchronize the dtv for the current coroutine.

[0095] In this embodiment, through the thread library function hook, a coroutine that is completely consistent with the thread capabilities can be simulated. The switching process of the coroutine is as follows: First, in the initial state of the coroutine scheduling thread, _current_coctx is the scheduler COCTX; then, when a coroutine needs to be swapped in (resume), it is checked whether there is a difference between the coroutine and the dtv incremental backup (if there is a difference, synchronization is required). After completing the difference synchronization, _current_coctx is set to the context of the current coroutine; finally, when the coroutine requests to be swapped out, _current_coctx is restored to the scheduler COCTX again. The entire coroutine switching process is completely executed in the user state without any form of interaction with the operating system, thus maintaining the lightweight feature of the coroutine.

[0096] This embodiment realizes the coroutine TLS switch in pure user space, maintaining the lightweight feature of coroutine switching while maintaining the cross-coroutine security of TLS (balancing high performance and "transparent" virtualization).

[0097] This embodiment provides a method for constructing a dynamic runtime library. By using the hook mechanism to construct the thread library function hook of the first library function in the native runtime library, replacing the original thread descriptor of the thread with the coroutine context in the thread library function hook, marking the current running entity through global variables, and managing the thread local storage information in the coroutine context structure through the synchronization management module, the constructed coroutine can have the same capabilities as the thread, improving the reliability of coroutine scheduling when the thread schedules the coroutine.

[0098] In the traditional technology, the coroutine library has not properly solved the compatibility problem between coroutine locks and thread locks. In some disclosed alternative implementation manners, constructing the dynamic runtime library based on the native runtime library of the application further includes:

[0099] Using the hook mechanism to construct the lock library function hook related to the second library function, where the second library function is the library function in the native runtime library related to locks, condition variables, and semaphores respectively; in the lock library function hook, judging the current running entity through the global variable with thread local constraints, and based on the current running entity, giving the corresponding lock mechanism for the current running entity.

[0100] In this alternative implementation manner, based on the request of the application, the current running entity can be a coroutine constructed through the dynamic runtime library or a thread constructed through running the native runtime library; through the global variable, the type of the running entity, whether it is a coroutine or a thread, can be identified. When the running entity is a thread, the thread library function hook further judges whether the current running entity is a coroutine scheduling thread or other threads. When the current running entity is a coroutine scheduling thread, no lock or semaphore mechanism is adopted. Through this mechanism, it can be ensured that the coroutine scheduling thread will not be suspended due to the use of locks or semaphores.

[0101] When the current running entity is a thread other than the coroutine scheduling thread (such as the main thread or the native thread), based on the current operating system, the wake-up signal is transmitted using the lock mechanism corresponding to the operating system. For example, when the operating system is the Linux system, the futex mechanism is used to transmit the wake-up signal; when the operating system is a non-Linux system, the wake-up signal is transmitted in the way of pipe communication and pollwait.

[0102] Futex mechanism: A synchronization mechanism that combines user space and kernel space, and is one of the basic components of Linux. State synchronization between user space and kernel space is achieved through atomic operations based on a shared memory segment. User-space processes use atomic operations to determine whether there is resource contention for futex variables. If waiting is required, they enter a system call to suspend the thread. When waking up a futex, they also first use atomic operations to check whether there are suspended waiting tasks, and only perform the "wake up" operation by entering a system call when waking up is required. Simply put, it avoids entering the kernel space without resource contention through user-space atomic operations, thus greatly improving the running efficiency in "low contention" scenarios.

[0103] In this optional implementation, the above-mentioned current running entity can also be an operation object without timeout waiting operations and an operation object with timeout waiting operations. Based on the above current running entity, the corresponding lock mechanism for the current running entity includes: for operations without timeout waiting, directly put the coroutine context structure into the waiting queue of the lock object or condition variable object, and call the "suspend" method (yield in the coroutine mode) on the coroutine context structure.

[0104] For operations with timeout waiting, it is necessary to put the coroutine context structure into the corresponding waiting queue and time queue at the same time, and then call the "suspend" method on the coroutine context structure.

[0105] This embodiment implements a lock mechanism that is "transparent" and compatible with both coroutines and threads. During the hook of lock-related library functions in the C runtime library, it automatically identifies whether it is in a coroutine context or a thread context, and thus adopts different behavior patterns.

[0106] The method for constructing a lock library function hook provided in this optional implementation hooks the thread lock-related library functions in the native runtime library, implementing a lock scheme that is compatible with both threads and coroutines, and ensuring the compatibility of thread locks and coroutine locks in the runtime virtual machine system.

[0107] In some optional implementations of the present disclosure, the construction of the dynamic runtime library based on the native runtime library of the application further includes:

[0108] Using a hook mechanism to construct a switching library function hook related to a third library function, where the third library function is a library function in the native runtime library that can cause thread switching or suspension operations; the switching library function hook is used to replace the thread switching or suspension mechanism with a coroutine switching or suspension mechanism.

[0109] The method for constructing a switching library function hook provided in this optional implementation hooks the functions in the native runtime library that can cause thread switching or suspension operations, and can use the switching and suspension methods of coroutines when switching or suspending threads, improving the concurrency performance of the operating system.

[0110] Further reference is made to Figure 2 , as an implementation of the runtime virtualization method shown in the above figures, the present disclosure provides an embodiment of a runtime virtualization device, and this device embodiment corresponds to Figure 2 the method embodiment shown, and this device can be specifically applied to various electronic devices.

[0111] As Figure 2 shown, an embodiment of the present disclosure provides a runtime virtualization device 200, and this device 200 includes: a construction unit 201, a generation unit 202, a task receiving unit 203, and a coroutine scheduling unit 204. Among them, the above construction unit 201 can be configured to build a dynamic runtime library based on the native runtime library of the application, and the dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner. The above generation unit 202 can be configured to load the dynamic runtime library when starting the application, generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, and the coroutine scheduling thread is used to schedule at least one coroutine. The runtime virtualization environment is the environment after replacing the generated runtime environment of the native runtime library. The above task receiving unit 203 can be configured to receive a task request of the application in the runtime virtualization environment. The above coroutine scheduling unit 204 can be configured to schedule the coroutine based on the task request and the dynamic runtime library by using the coroutine scheduling thread, so that the coroutine completes the task corresponding to the task request.

[0112] In this embodiment, in the runtime virtualization device 200, the specific processing of the construction unit 201, the generation unit 202, the task receiving unit 203, and the coroutine scheduling unit 204 and the technical effects brought by them can be respectively referred to Figure 1 steps 101, 102, 103, and 104 in the corresponding embodiments.

[0113] In some embodiments, the above scheduling unit 204 is configured to: create at least one coroutine based on the task request and the dynamic runtime library; send at least one coroutine to the coroutine scheduling thread to schedule at least one coroutine by using the coroutine scheduling thread.

[0114] In some embodiments, the above-mentioned coroutine scheduling thread includes: a scheduler and a lock-free queue for placing at least one coroutine. The scheduling unit 204 is further configured such that: the scheduler obtains a coroutine in a ready state from the lock-free queue among the at least one coroutine; synchronizes the coroutine context of the coroutine with the thread context in the thread control block; after the coroutine actively yields, the scheduler obtains the next coroutine in a ready state from the lock-free queue and synchronizes the coroutine context of the next coroutine with the thread context in the thread control block; after the next coroutine actively yields, the scheduler continues to obtain coroutines from the lock-free queue and synchronize the thread control block until there are no coroutines in the lock-free queue.

[0115] In some embodiments, the above-mentioned device 200 further includes: a native receiving unit configured to receive a native request of an application; a thread scheduling unit configured to create at least one thread based on the native request and a dynamic runtime library, and execute a task corresponding to the native request through the at least one thread.

[0116] In some embodiments, the above-mentioned building unit 201 is configured to: use a hook mechanism to build a thread library function hook related to a first library function, where the first library function is a library function in the native runtime library for creating a thread and obtaining a thread descriptor; in the thread library function hook, replace the thread descriptor with a coroutine context structure, mark the currently running thread or coroutine through a global variable with thread-local constraints, and manage the thread-local storage information in the coroutine context structure through a synchronization management module, where the synchronization management module is used to synchronize the thread-local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.

[0117] In some embodiments, the above-mentioned building unit 201 is configured to: use a hook mechanism to build a lock library function hook related to a second library function, where the second library function is a library function in the native runtime library related to locks, condition variables, and semaphores respectively; in the lock library function hook, determine the currently running entity through a global variable, and give a corresponding lock mechanism for the currently running entity based on the currently running entity.

[0118] In some embodiments, the above-mentioned building unit 201 is configured to: use a hook mechanism to build a switching library function hook related to a third library function, where the third library function is a library function in the native runtime library that can cause a thread switching or suspension operation; the switching library function hook is used to replace the thread switching or suspension mechanism with a coroutine switching or suspension mechanism.

[0119] The runtime virtualization device provided by the embodiments of the present disclosure, first, a construction unit 201 constructs a dynamic runtime library based on the native runtime library of an application; second, a generation unit 202 loads the dynamic runtime library when starting the application, generates a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, the coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is an environment after replacing the runtime environment of the native runtime library; third, a task receiving unit 203 receives a task request of the application in the runtime virtualization environment; finally, a coroutine scheduling unit 204 schedules the coroutine based on the task request and the dynamic runtime library by using the coroutine scheduling thread, so that the coroutine completes the task corresponding to the task request. Thus, the present disclosure generates a runtime virtualization environment through the dynamic runtime library, transparently replaces the runtime environment of the application, and improves the concurrency performance of the application without making any modifications or recompiling the application; the coroutine with thread capabilities generated by the dynamic runtime library supports lightweight coroutine scheduling, which can effectively control the occupancy rate of thread resources in the system, reduce system resource consumption and resource scheduling pressure, thereby improving the overall throughput and availability of the system.

[0120] For the above runtime virtualization method, the present disclosure provides a runtime virtual machine system, which can be specifically applied to various electronic devices.

[0121] As Figure 3 shown, the embodiments of the present disclosure provide a runtime virtual machine system 300, and the system 300 includes: a main thread 302, a coroutine scheduling thread 303, an event-driven thread 304, and an asynchronous input / output and timer thread 305 running in a runtime virtualization environment 301. Among them, the runtime virtualization environment 301 is generated by loading a dynamic runtime library, and the dynamic runtime library is constructed based on the native runtime library of the application. The dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner; the coroutine scheduling thread 303 is used to schedule at least one coroutine so that the coroutine completes the task request of the application; the main thread 302 is created when the application starts; the event-driven thread 304 is used to maintain the status of the file handle, and wakes up the corresponding coroutine when the read or write cache is ready and there are read and write tasks blocked on the file handle; the asynchronous input / output and timer thread 305 obtains the result of the asynchronous input / output task and wakes up the coroutine in the IO wait state; when the system call times out and returns, pops up the timed-out task and wakes it up; when the system calls the result of the asynchronous IO task, wakes up the coroutine in the IO wait state.

[0122] The main thread 302 is created when the application starts and can be regarded as a special system native thread.

[0123] The coroutine scheduling thread 303 is responsible for repeatedly retrieving ready coroutine tasks from the lock-free queue, swapping in the coroutine context using the resume method (including newly started coroutines), and continuing to execute the corresponding coroutines. When a coroutine yields (including when the coroutine ends), if it is a non-waiting coroutine (i.e., it only temporarily yields the CPU), the corresponding coroutine needs to be put back into the wake-up queue and rescheduled. The runtime virtual machine system of the present disclosure adopts the boost context library in practice to implement the switching of coroutine stacks and the swapping in and out of coroutine functions.

[0124] The asynchronous input / output and timer thread 305, which is the background part of asynchronous I / O and timers, can be implemented in the same background thread. This is because the system call interface for waiting for asynchronous I / O events can specify a timeout, and the time precision of such timeouts is also high enough to be suitable for the implementation of timers. As a background thread with a low load, combining the above two functions helps to further reduce the number of background threads. The asynchronous input / output and timer thread 305 interacts with other components in the system through two data structures:

[0125] AIO task queue: used to transfer the io_event of asynchronous I / O tasks. After the background thread calls io_getevents to return the result, it will search this queue, transfer the I / O operation result, and wake up the coroutines waiting for I / O.

[0126] Timed queue: manages the coroutine contexts in the timeout waiting state. This queue stores a key-value structure, with the timeout as the key and the COCTX as the value, and is sorted by the key value (the task with a smaller key value - that is, the task with the shortest time interval from the current time - is ranked first).

[0127] This background thread repeatedly calls the io_getevents system call. When this call times out and returns, it processes the timed queue, pops and wakes up the tasks whose timeouts have expired (which may be either coroutines or native threads); when the system call returns the result of an asynchronous I / O task, it transfers the content of the io_event structure and wakes up the corresponding coroutine.

[0128] The event-driven thread 304, also known as the Epoll thread, is responsible for maintaining the POLLIN & POLLOUT states of all open file handles in the system that support the poll operation. Since the dynamic runtime library has hooked library functions including socket, open, close, etc., when a file handle (mainly a socket) is newly created, it is placed in the sockfd map for maintenance. This thread repeatedly updates the read / write buffer states of all file handles in the sockfd map by calling epoll_wait. When the read / write buffer is ready and there are currently read / write tasks or poll wait tasks (such as coroutines waiting in the hooks of library functions like poll, select, epoll_wait, etc.) blocked on this file handle, the corresponding coroutine is awakened.

[0129] For the above-mentioned runtime virtual machine system, to minimally start an application that mounts the runtime virtual machine, only 4 threads need to be created, namely: 1 main thread, 1 coroutine scheduling thread, 1 event-driven thread, and 1 asynchronous input / output and timer thread. Even when starting a process with the above minimal resource configuration (i.e., only 4 threads), it can still easily handle hundreds of small concurrent tasks without lag. When facing large-scale applications with high resource occupancy (such as databases), the number of coroutine scheduling threads equal to the number of host CPU cores can be considered, and other background threads can be configured in a proportionally reduced manner. That is to say, whether it is an application scenario with many small tasks and multiple processes or many large tasks and multiple threads, the runtime virtual machine of the present disclosure can provide good support. Specific examples are as follows:

[0130] In the first case, all processes are started with the minimal configuration (4 threads), and the average load of each process is 100 small tasks. When 1000 processes are started, the overall system load reaches 100,000 concurrences, but only 4000 threads need to be created.

[0131] In the second case, in a 64-core system, only one large-scale application (such as a database) is started, including: 1 main thread, 64 coroutine scheduling threads, 8 epoll threads, 8 AIO / timer threads, and 10 background threads of the database (such as: publish / subscribe, backup / restore, monitoring, log cleaning, tablespace recycling and reorganization, etc., all using native system threads), for a total of 91 threads. Such a configuration is sufficient to handle hundreds of thousands of database concurrent accesses, and the total number of threads is less than 100.

[0132] The runtime virtual machine system provided by the embodiments of the present disclosure provides a complete set of coroutine-based dynamic runtime libraries through dynamic library injection technology. All the ways of interacting with the operating system have been taken over by the hooks of the dynamically running library functions in the present disclosure (that is, a complete set of coroutine versions of library functions has been implemented). The application runs virtually on another virtual system that is fully compatible with the native system, namely the coroutine virtualization environment. Any application in the host system can run directly in the coroutine virtualization environment without any modification, transparently implementing the solution of replacing threads with coroutines.

[0133] In another embodiment of the present disclosure, a runtime virtual machine system 400 is further provided. The system 400 includes: a main thread 402, a coroutine scheduling thread 403, an event-driven thread 404, an asynchronous input / output and timer thread 305, and a system native thread 306 running under the runtime virtualization environment 401.

[0134] Relative to Figure 3 the illustrated embodiment, Figure 4 the illustrated embodiment has a system native thread 306, Figure 4 the illustrated embodiment relative to Figure 3 the illustrated embodiment, the generated dynamic runtime library retains the characteristics of the native runtime library. Through the native runtime library, the native runtime library can be called when the application has a need, and the system native thread 306 is generated.

[0135] Since the library functions related to thread management have all been hooked, by default, all created after loading the dynamic runtime library are coroutines. When the application has a need to generate a system native thread, the user can choose to start the corresponding thread in the native thread manner by specifying the function name of the thread function; or by implementing the callback interface corresponding to the library function for creating a thread, dynamically specify whether a newly created thread is started in the coroutine manner or in the native thread manner.

[0136] Optionally, the runtime virtual machine system provided in this embodiment, in addition to common interfaces such as parameter configuration interfaces and log interfaces; also implements a set of callback interfaces, and most of the library function hooks in the dynamic runtime library can be equipped with corresponding callback functions. Developers can choose to implement some or all of the callbacks, or not use any callbacks. Through these callback interfaces, developers can partially change the behavior of library functions, or even completely take over certain specific library functions, so as to achieve, for example:

[0137] Inject some optimizations that originally required modifying the underlying system mechanism directly into the library functions; and this injection is only for the current application and will not affect other running programs;

[0138] Perform secondary development based on the runtime virtual machine system of the present disclosure to implement another set of runtime virtual machine systems. (For example, take over all library functions related to file I / O, and change local file reading and writing to cloud disk reading and writing, then a runtime virtual machine based on cloud disk can be implemented).

[0139] Taking the callback of a recv (receive network packet) interface as an example, illustrate the running logic of the callback function in the runtime virtual machine system of the present disclosure. When the developer specifies a callback function, the recv function of the runtime virtual machine system of the present disclosure will first pass the network packet received from the socket to the callback function, and determine the final return method of the recv function according to the return value of the callback function. The callback function can choose not to intervene at all and directly return this packet; it can also choose to discard this packet; or even further modify the content of the packet and return the modified packet to the application.

[0140] The runtime virtual machine system provided in this embodiment provides a callback interface. Developers can inject new logic into the hook of the coroutine library or completely change the logic of the hook function by implementing callback functions, so as to achieve the extension and enhancement of the original application program, or implement a brand-new runtime virtualization environment with the help of this runtime virtual machine framework.

[0141] The following refers to Figure 5 , which shows a schematic structural diagram of an electronic device 500 suitable for implementing the embodiments of the present disclosure.

[0142] As Figure 5 shown, the electronic device 500 may include a processing device (such as a central processing unit, a graphics processing unit, etc.) 501, which can perform various appropriate actions and processes according to the program stored in the read-only memory (ROM) 502 or the program loaded from the storage device 508 into the random access memory (RAM) 503. In the RAM 503, various programs and data required for the operation of the electronic device 500 are also stored. The processing device 501, the ROM 502, and the RAM 503 are connected to each other through a bus 504. The input / output (I / O) interface 505 is also connected to the bus 504.

[0143] Generally, the following devices can be connected to the I / O interface 505: an input device 506 including, for example, a touch screen, a touchpad, a keyboard, a mouse, etc.; an output device 507 including, for example, a liquid crystal display (LCD, Liquid Crystal Display), a speaker, a vibrator, etc.; a storage device 508 including, for example, a magnetic tape, a hard disk, etc.; and a communication device 509. The communication device 509 can allow the electronic device 500 to communicate with other devices wirelessly or wiredly to exchange data. Although Figure 5An electronic device 500 is shown with various devices, but it should be understood that it is not required to implement or have all the devices shown. Instead, more or fewer devices may be implemented or had. Figure 5 Each block shown in Figure 5 may represent a device or, as needed, multiple devices.

[0144] In particular, according to an embodiment of the present disclosure, the processes described above with reference to the flowcharts may be implemented as computer software programs. For example, an embodiment of the present disclosure includes a computer program product that includes a computer program carried on a computer-readable medium, and the computer program includes program code for performing the methods shown in the flowcharts. In such an embodiment, the computer program may be downloaded and installed from a network via a communication device 509, or installed from a storage device 508, or installed from a ROM 502. When the computer program is executed by a processing device 501, the above-described functions defined in the methods of the embodiments of the present disclosure are performed.

[0145] It should be noted that the computer-readable medium in the embodiments of the present disclosure may be a computer-readable signal medium or a computer-readable storage medium or any combination of the two. A computer-readable storage medium may be, for example, but not limited to, an electrical, magnetic, optical, electromagnetic, infrared, or semiconductor system, apparatus, or device, or any combination of the above. More specific examples of the computer-readable storage medium may include, but are not limited to: an electrical connection having one or more wires, a portable computer disk, a hard disk, a random access memory (RAM), a read-only memory (ROM), an erasable programmable read-only memory (EPROM or flash memory), an optical fiber, a portable compact disk read-only memory (CD-ROM), an optical storage device, a magnetic storage device, or any suitable combination of the above. In the embodiments of the present disclosure, the computer-readable storage medium may be any tangible medium that contains or stores a program that can be used by or in conjunction with an instruction execution system, apparatus, or device. And in the embodiments of the present disclosure, the computer-readable signal medium may include a data signal propagated in a baseband or as part of a carrier wave, which carries computer-readable program code. Such a propagated data signal may take various forms, including but not limited to electromagnetic signals, optical signals, or any suitable combination of the above. The computer-readable signal medium may also be any computer-readable medium other than the computer-readable storage medium, and the computer-readable signal medium may send, propagate, or transmit a program for use by or in conjunction with an instruction execution system, apparatus, or device. The program code contained on the computer-readable medium may be transmitted using any appropriate medium, including but not limited to: wires, optical cables, RF (Radio Frequency), etc., or any suitable combination of the above.

[0146] The above computer-readable medium may be included in the server; or may exist independently without being assembled into the server. The above computer-readable medium carries one or more programs, and when the one or more programs are executed by the server, the server is caused to: build a dynamic runtime library based on the native runtime library of the application; load the dynamic runtime library when starting the application to generate a coroutine scheduling thread for scheduling at least one coroutine; receive a task request of the application; and schedule the coroutine using the coroutine scheduling thread based on the task request and the dynamic runtime library so that the coroutine completes the task corresponding to the task request.

[0147] Computer program code for performing the operations of the embodiments of the present disclosure may be written in one or more programming languages or combinations thereof. The programming languages include object-oriented programming languages such as Java, Smalltalk, C++, and also include conventional procedural programming languages such as the "C" language or similar programming languages. The program code may execute entirely on the user's computer, partly on the user's computer, as a stand-alone software package, partly on the user's computer and partly on a remote computer, or entirely on the remote computer or server. In the case of a remote computer, the remote computer may be connected to the user's computer through any type of network, including a local area network (LAN) or a wide area network (WAN), or may be connected to an external computer (for example, through the Internet using an Internet service provider).

[0148] The flowcharts and block diagrams in the accompanying drawings illustrate the possible architectures, functions, and operations of systems, methods, and computer program products according to various embodiments of the present disclosure. In this regard, each block in the flowchart or block diagram may represent a module, a program segment, or a part of code that contains one or more executable instructions for implementing the specified logical function. It should also be noted that in some alternative implementations, the functions marked in the blocks may occur in a different order than marked in the accompanying drawings. For example, two consecutive blocks shown may actually be executed substantially in parallel, and they may sometimes be executed in the reverse order, depending on the functions involved. It should also be noted that each block in the block diagram and / or flowchart, and combinations of blocks in the block diagram and / or flowchart, may be implemented by a dedicated hardware-based system for performing the specified functions or operations, or may be implemented by a combination of dedicated hardware and computer instructions.

[0149] The units involved in the embodiments described in this disclosure can be implemented in software or in hardware. The described units can also be provided in a processor. For example, it can be described as: a processor including a construction unit, a generation unit, a task receiving unit, and a coroutine scheduling unit. Among them, the names of these units do not constitute a limitation to the unit itself in some cases. For example, the construction unit can also be described as a unit "configured to construct a dynamic runtime library based on the native runtime library of an application".

[0150] The above description is only for the preferred embodiments of this disclosure and the explanation of the applied technical principles. Those skilled in the art should understand that the scope of the invention involved in the embodiments of this disclosure is not limited to the technical solutions formed by the specific combination of the above technical features, and should also cover other technical solutions formed by any combination of the above technical features or their equivalent features without departing from the above inventive concept. For example, the technical solutions formed by mutually replacing the above features with the (but not limited to) technical features having similar functions disclosed in the embodiments of this disclosure.

Claims

1. A runtime virtualization method, the method comprising: Build a dynamic runtime library based on the native runtime library of the application, and the dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner; When starting the application, load the dynamic runtime library to generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment. The coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is the environment after replacing the native runtime library; Under the runtime virtualization environment, receive the task request of the application; Based on the task request and the dynamic runtime library, use the coroutine scheduling thread to schedule the coroutine so that the coroutine completes the task corresponding to the task request; Among them, building a dynamic runtime library based on the native runtime library of the application includes: Use the hook mechanism to build a thread library function hook related to the first library function. The first library function is the library function for creating threads and obtaining thread descriptors in the native runtime library; In the thread library function hook, replace the thread descriptor with a coroutine context structure, mark the currently running thread or coroutine through a global variable with thread local constraints, and manage the thread local storage information in the coroutine context structure through a synchronization management module. The synchronization management module is used to synchronize the thread local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.

2. The method according to claim 1, wherein, The step of using the coroutine scheduling thread to schedule the coroutine based on the task request and the dynamic runtime library so that the coroutine completes the task corresponding to the task request includes: Based on the task request and the dynamic runtime library, create at least one coroutine; Send the at least one coroutine to the coroutine scheduling thread to use the coroutine scheduling thread to schedule the at least one coroutine.

3. The method according to claim 2, wherein, The coroutine scheduling thread includes: a scheduler and a lock-free queue for placing the at least one coroutine. The step of using the coroutine scheduling thread to schedule the at least one coroutine includes: The scheduler obtains the coroutine in the ready state among the at least one coroutine from the lock-free queue; Synchronize the coroutine context of the coroutine with the thread context in the thread control block; After the coroutine actively yields, the scheduler obtains the next coroutine in the ready state from the lock-free queue and synchronizes the coroutine context of the next coroutine in the ready state with the thread context in the thread control block; After the next coroutine in the ready state actively yields, the scheduler continues to obtain coroutines from the lock-free queue and synchronize the thread control block until there are no coroutines in the lock-free queue.

4. The method according to claim 1, wherein, The method further includes: Receive the native request of the application; Based on the native request and the native runtime library in the dynamic runtime library, create at least one thread, and execute the task corresponding to the native request through the at least one thread.

5. The method according to claim 1, wherein, Building a dynamic runtime library based on the native runtime library of the application further includes: Use the hook mechanism to construct lock library function hooks related to the second library functions, where the second library functions are the library functions in the native runtime library related to locks, condition variables, and semaphores respectively; In the lock library function hooks, judge the currently running entity through the global variable, and based on the currently running entity, give the corresponding lock mechanism for the currently running entity.

6. The method according to claim 1, wherein, The constructing of the dynamic runtime library based on the native runtime library of the application further includes: Use the hook mechanism to construct switch library function hooks related to the third library functions, where the third library functions are the library functions in the native runtime library that can cause thread switching or suspension operations; The switch library function hooks are used to replace the thread switching or suspension mechanism with a coroutine switching or suspension mechanism.

7. A runtime virtualization device, the device comprising: A construction unit configured to construct a dynamic runtime library based on the native runtime library of the application, where the dynamic runtime library simulates the threads implemented in the native runtime library in a coroutine manner; A generation unit configured to load the dynamic runtime library when starting the application, generate a runtime virtualization environment and a coroutine scheduling thread running in the runtime virtualization environment, where the coroutine scheduling thread is used to schedule at least one coroutine, and the runtime virtualization environment is the environment after replacing the native runtime library-generated runtime environment; A task receiving unit configured to receive task requests of the application in the runtime virtualization environment; A coroutine scheduling unit configured to schedule coroutines using the coroutine scheduling thread based on the task request and the dynamic runtime library, so that the coroutines complete the tasks corresponding to the task requests; Wherein, the construction unit is further configured to: Use the hook mechanism to construct thread library function hooks related to the first library functions, where the first library functions are the library functions in the native runtime library for creating threads and obtaining thread descriptors; In the thread library function hooks, replace the thread descriptor with a coroutine context structure, mark the currently running thread or coroutine through a global variable with thread-local constraints, and manage the thread-local storage information in the coroutine context structure through a synchronization management module, where the synchronization management module is used to synchronize the thread-local storage of the coroutine when the coroutine scheduling thread schedules the coroutine.

8. A runtime virtual machine system, the system comprising: A coroutine scheduling thread, a main thread, an event-driven (EPOLL) thread, and an asynchronous input / output (AIO) and timer thread running in a runtime virtualization environment, wherein the runtime virtualization environment is generated by loading a dynamic runtime library, and the dynamic runtime library is constructed based on the native runtime library of the application. A thread library function hook related to the first library function is constructed using a hook mechanism. The first library function is a library function in the native runtime library for creating a thread and obtaining a thread descriptor. In the thread library function hook, a coroutine context structure is used to replace the thread descriptor, and a global variable with thread-local constraints is used to mark the currently running thread or coroutine. The thread-local storage information in the coroutine context structure is managed by a synchronization management module, which is used to synchronize the thread-local storage of a coroutine when the coroutine scheduling thread schedules the coroutine. The dynamic runtime library emulates the threads implemented in the native runtime library in a coroutine manner; The coroutine scheduling thread is used to schedule at least one coroutine so that the coroutine completes the task request of the application; The main thread is created when the application starts; The event-driven thread is used to maintain the status of file handles and wake up the corresponding coroutine when the read or write cache is ready and there are read / write tasks blocked on the file handle; The asynchronous input / output and timer thread obtains the results of asynchronous input / output tasks and wakes up the coroutines waiting for I / O; when the system call times out and returns, it pops up the timed-out tasks and wakes them up; when the system call obtains the results of asynchronous I / O tasks, it wakes up the coroutines waiting for I / O.

9. An electronic device, comprising: One or more processors; A storage device on which one or more programs are stored; When the one or more programs are executed by the one or more processors, the one or more processors implement the method according to any one of claims 1-6.

10. A computer-readable medium having a computer program stored thereon, wherein, When the program is executed by a processor, it implements the method according to any one of claims 1-6.

Citation Information

Patent Citations

  • Coroutine-based data processing method and device, computer equipment and storage medium

    CN111078323A

  • Data interaction method and device for Linux kernel mode and user mode

    CN114356598A

Cited By

  • Runtime virtualization method and apparatus, and runtime virtual machine system

    EP4657252A1