A method and apparatus for cross-language execution
By establishing a shared memory mapping area between the Java and Python language environments and employing a task scheduler and an embedded execution engine, the performance bottleneck problem in Java and Python language calls and data transmission is solved, achieving efficient, reliable, and timely cross-language data transmission and task processing.
Patent Information
- Application Number
- CN202512035844.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-12-31
- Publication Date
- 2026-04-07
- Estimated Expiration
- 2045-12-31
AI Technical Summary
Java and Python face significant performance bottlenecks and efficiency gaps when making mutual calls and transferring data, especially in high-frequency application scenarios. The frequent process startup and destruction operations caused by the traditional process-level call mechanism generate significant system overhead and cannot meet the response latency requirements.
By establishing a shared memory mapping area between the Java and Python language environments, zero-copy cross-language data transmission is achieved. A task scheduler and an embedded execution engine are used to manage cross-language call requests. By utilizing shared memory and flag-based communication mechanisms, the performance loss caused by data copying and serialization is avoided, ensuring the reliability and timeliness of data transmission.
It achieves zero-copy cross-language data transmission, eliminates the performance overhead of serialization and deserialization, ensures the reliability and timeliness of data transmission, and efficiently handles concurrent requests through thread pools and asynchronous monitoring mechanisms, optimizes resource allocation, and improves the real-time performance and continuity of task processing.
Smart Images

Figure CN121433850B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of software development technology, and in particular to a method and apparatus for cross-language execution. Background Technology
[0002] With the deep integration of artificial intelligence, data analytics, and enterprise-level backend systems, modern software systems increasingly require the collaborative use of both Java and Python programming languages within the same application process. Java, with its robust high-performance characteristics, rigorous type safety mechanisms, and mature multithreaded concurrency model, dominates the enterprise application backend service field. Meanwhile, Python, with its flexible syntax and rich ecosystem of scientific computing libraries, plays an irreplaceable role in scenarios such as data processing, machine learning modeling, and automated scripting tasks.
[0003] However, Java and Python fundamentally belong to different runtime architectures. Java programs typically run on a Java Virtual Machine (JVM) environment, while Python programs primarily rely on the Python interpreter for execution. This fundamental difference in runtime environments leads to significant performance bottlenecks and efficiency gaps when the two languages call each other and transfer data. Currently, several typical technical solutions exist in the industry to achieve interoperability between Java and Python. One solution is a process-level call mechanism, which uses Java's `Runtime.exec()` method or the `ProcessBuilder` class to start an external Python interpreter process to execute script files. Although this method is relatively simple and direct in implementation, its inherent drawback is that a new Python process needs to be created for each cross-language call. The frequent process startup and destruction operations result in significant system overhead, leading to a significant increase in response latency, which cannot meet the needs of high-frequency call application scenarios. Summary of the Invention
[0004] This specification provides a method and apparatus for cross-language execution to solve at least one of the technical problems mentioned above.
[0005] According to a first aspect of the present invention, a method for cross-language execution is provided for implementing code calls and data interaction between Java and Python language environments, comprising the following steps:
[0006] Establish a shared memory mapping area between the Java client and the Python client, which is accessible to both the Java client and the Python client.
[0007] The Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets a flag bit;
[0008] On the Java side, a thread pool is used through a task scheduler to manage the execution process of cross-language function call requests. The task scheduler allocates threads according to task priority.
[0009] The Python side monitors the flag bit of the shared memory mapping area through the embedded execution engine. When the flag bit is detected to be set, the input data is read from the shared memory mapping area and deserialized, the corresponding Python function is executed, the execution result is serialized and written back to the shared memory mapping area, and the flag bit is reset.
[0010] The Java side monitors the flag bit of the shared memory mapping area. When it detects that the flag bit has been reset, it reads and deserializes the execution result from the shared memory mapping area.
[0011] In some alternative implementations, establishing a shared memory mapping area between Java and Python includes:
[0012] In Java, a MappedByteBuffer instance is created using the map method of FileChannel;
[0013] On the Python side, the mmap module is used to create memory mappings based on the same file paths as on the Java side.
[0014] The MappedByteBuffer created on the Java side and the memory-mapped object created on the Python side point to the same memory region.
[0015] In some alternative implementations, the thread pool is a fixed-size thread pool configured for multiple threads to execute concurrently, with each thread independently operating on different data regions of the shared memory mapping area.
[0016] In some alternative implementations, the task priority is determined by a formula. Calculation determines; where, the symbol Indicates the estimated time of the task, symbol Indicates the average task time, symbol This represents the adjustment coefficient.
[0017] In some optional implementations, the Python side monitors the flags of the shared memory mapping region through an embedded execution engine, including:
[0018] After startup, the embedded execution engine remains resident in memory and runs an asynchronous event loop.
[0019] The asynchronous event loop continuously polls and checks the status of the flag bits in the shared memory mapping area.
[0020] When the flag is detected to be a preset set value, an independent asynchronous task is created through the asynchronous event loop to process the input data;
[0021] The asynchronous event loop continues to run after the asynchronous task is created, either processing other tasks or continuing to monitor the flag status.
[0022] In some optional implementations, the method further includes: releasing the shared memory mapping area when the system exits, wherein releasing the shared memory mapping area includes: the Java side calling a resource cleanup function on the Python side, the Python side performing a memory mapping shutdown operation, and deleting the temporary files used for memory mapping.
[0023] In some optional implementations, the Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets flag bits, including:
[0024] The Java side uses a binary serialization protocol to serialize the input data;
[0025] The serialized input data is written into the data area of the shared memory mapping region;
[0026] Set a flag bit to a preset value at a predetermined location in the shared memory mapping area.
[0027] In some optional implementations, the Java side monitors the flag bit of the shared memory mapping area, and when it detects that the flag bit has been reset, it reads and deserializes the execution result from the shared memory mapping area, including:
[0028] The Java client continuously checks the status of the flag bits of the shared memory mapping area through polling.
[0029] When the flag is detected to change from the set state to the reset state, the execution result data is read from the shared memory mapping area;
[0030] The read execution result data is deserialized to obtain the execution result of the Python function.
[0031] In some optional implementations, when multiple function execution requests are detected within a preset time window, the multiple requests are merged into a batch processing task;
[0032] The batch processing task involves unified scheduling and execution of multiple function execution requests.
[0033] The execution results of multiple functions are written back to the shared memory mapping area.
[0034] The technical solution of this application has several significant technical advantages, as detailed below:
[0035] 1. The technical solution of this application establishes a shared memory mapping area between the Java and Python sides, enabling two different runtime environments to directly access the same physical memory region. This avoids the data copying operations necessary for inter-process communication or network transmission in traditional cross-language calls. The Java side directly writes serialized data into shared memory and sets a flag bit. The Python side directly reads and processes the data by monitoring the changes in the flag bit state. This mechanism based on shared memory and flag bit communication can achieve zero-copy cross-language data transmission, eliminating the performance loss caused by serialization and deserialization. At the same time, the status management of the flag bit can ensure the reliability and timeliness of data transmission.
[0036] 2. In the technical solution of this application, the Java side uses a thread pool to manage cross-language call requests through a task scheduler and allocates thread resources according to task priority. This design can efficiently handle concurrent requests and optimize resource allocation. The Python side adopts an embedded execution engine and asynchronous monitoring mechanism, which can process new tasks in a timely manner and write back the results, ensuring the real-time and continuous nature of task processing. Attached Figure Description
[0037] To more clearly illustrate the technical solutions in the embodiments or prior art of this specification, the drawings used in the description of the embodiments or prior art will be briefly introduced below. Obviously, the drawings described below are only some embodiments recorded in this application. For those skilled in the art, other drawings can be obtained based on these drawings without creative effort.
[0038] Figure 1 A flowchart illustrating a method for cross-language execution provided in an embodiment of this application;
[0039] Figure 2 A schematic diagram illustrating the interaction between the Java side and the Python interpreter in the cross-language execution method provided in this application embodiment;
[0040] Figure 3 A schematic diagram illustrating the interaction relationships among the modules of the apparatus for implementing the cross-language execution method provided in the embodiments of this application. Detailed Implementation
[0041] To make the objectives, technical solutions, and advantages of one or more embodiments of this specification clearer, the technical solutions of one or more embodiments of this specification will be clearly and completely described below in conjunction with specific embodiments and corresponding drawings. Obviously, the described embodiments are only a part of the embodiments of this specification, and not all of them. Based on the embodiments in this specification, all other embodiments obtained by those skilled in the art without creative effort are within the protection scope of one or more embodiments of this specification.
[0042] It should be understood that although the terms first, second, third, etc., may be used in this application to describe various information, this information should not be limited to these terms. These terms are only used to distinguish information of the same type from one another.
[0043] This application provides a method for cross-language execution, used to achieve code calling and data interaction between Java and Python language environments, such as... Figure 1 As shown, the method may include the following steps:
[0044] Step 102: Establish a shared memory mapping area between the Java client and the Python client, which is accessible to both the Java client and the Python client.
[0045] This step provides a unified memory access channel for both the Java and Python runtime environments by mapping them to the same memory region. On the Java side, a direct byte buffer instance of a specified size can be created using file channel mapping methods. This instance is associated with a specific temporary file created in the file system and configured for read-write memory mapping. Simultaneously, on the Python side, the memory mapping module can be used to create a corresponding memory-mapped object by opening the exact same temporary file as on the Java side and specifying the same memory mapping size.
[0046] In this step, through the operations described above, the direct byte buffer on the Java side and the memory-mapped object on the Python side can be mapped to the same memory address space in the kernel with the help of the operating system's memory management mechanism.
[0047] Step 104: The Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets the flag bit.
[0048] In this step, the serialization process can employ the MessagePack binary protocol to convert the input data object into a compact binary format. The converted binary data blocks are then written to the data area of the shared memory map. To ensure that multiple consecutive data blocks can be correctly identified and read, the memory offset address needs to be accurately calculated during writing, i.e., the [number of blocks]. The starting write position of each data block is equal to the starting address of the shared memory region plus the previous address. -1 is the sum of the lengths of data blocks. After the data is successfully written, the Java side can set a flag to a preset value at a pre-agreed specific location in the shared memory mapping area. This flag serves as an inter-process communication signal, explicitly indicating to the Python side that new input data is ready and can be read and processed immediately.
[0049] Step 106: On the Java side, the execution process corresponding to cross-language function call requests is managed by a thread pool through a task scheduler. The task scheduler allocates threads according to task priority.
[0050] In this technical solution, the Java-side task scheduler can use a fixed-size thread pool to receive and manage all cross-language function call requests. The scheduler can allocate a suitable thread to each pending request according to a preset task priority algorithm. The selected thread is then independently responsible for the complete execution process of the request, including writing task data to shared memory, waiting for processing on the Python side, and finally reading and returning the result.
[0051] Step 108: The Python side monitors the flag bit of the shared memory mapping area through the embedded execution engine. When the flag bit is detected to be set, the input data is read from the shared memory mapping area and deserialized, the corresponding Python function is executed, the execution result is serialized and written back to the shared memory mapping area, and the flag bit is reset.
[0052] In this step, the embedded execution engine can refer to a dedicated Python runtime environment that resides in memory. It continuously monitors shared memory through an internal asynchronous event loop. When it detects a task request from the Java side, it automatically executes the specified Python function and returns the result. This engine is deeply embedded in the cross-language architecture and is specifically responsible for handling function calls from the Java side.
[0053] Step 110: The Java side monitors the flag bit of the shared memory mapping area. When the flag bit is detected to be reset, the execution result is read from the shared memory mapping area and deserialized.
[0054] In this technical solution, the Java side needs to start a monitoring mechanism to continuously check the status of the flag bit in the shared memory. When the flag bit changes from a set state (e.g., value 1) back to a reset state (e.g., value 0), it can be determined that the Python side has completed the task processing. Subsequently, the Java side reads the binary result data from the specified data area of the shared memory and converts it into a Java object using the same deserialization protocol as when writing, thereby obtaining the final execution result of the Python function.
[0055] This application's technical solution establishes a shared memory mapping area between the Java and Python sides, enabling two different runtime environments to directly access the same physical memory region. This avoids the data copying operations necessary for inter-process communication or network transmission in traditional cross-language calls. The Java side directly writes serialized data into shared memory and sets a flag, while the Python side directly reads and processes the data by monitoring changes in the flag's state. This mechanism, based on shared memory and flag communication, achieves zero-copy cross-language data transmission, eliminating the performance overhead of serialization and deserialization. Furthermore, flag state management ensures the reliability and timeliness of data transmission. In addition, this application's technical solution uses a thread pool managed by a task scheduler in the Java side to manage cross-language call requests and allocates thread resources according to task priority. This design efficiently handles concurrent requests and optimizes resource allocation. The Python side employs an embedded execution engine and asynchronous monitoring mechanism, enabling timely processing and writing back results when new tasks are detected, ensuring the real-time and continuous nature of task processing.
[0056] Based on the technical solutions described above, this specification also provides some specific implementation schemes, which are described below.
[0057] In an optional embodiment, establishing a shared memory mapping area between Java and Python may include:
[0058] In Java, a MappedByteBuffer instance is created using the map method of FileChannel;
[0059] On the Python side, the mmap module is used to create memory mappings based on the same file paths as on the Java side.
[0060] The MappedByteBuffer created on the Java side and the memory-mapped object created on the Python side point to the same memory region.
[0061] In this embodiment, when establishing a shared memory mapping area between Java and Python, the Java side can use the `map` method of `FileChannel` to directly map a specified area of a disk file to the memory space of the Java process, creating a `MappedByteBuffer` instance. This instance is a direct memory buffer, directly associated with the physical storage of the disk file, and serves as the entry point for Java to operate on shared memory. Simultaneously, the Python side can create a memory-mapped object using the `mmap` module based on the exact same file path as the Java side. Since both map to the same area of the same disk file, the `MappedByteBuffer` created by the Java side and the memory-mapped object created by the Python side ultimately point to the same memory area.
[0062] In an optional embodiment, the thread pool is a fixed-size thread pool configured for multiple threads to execute concurrently, with each thread independently operating different data regions of the shared memory mapping area.
[0063] In this embodiment, the Java side can pre-initialize a thread pool containing a fixed number of worker threads. The number of threads can be set at system startup and remains constant during runtime, thus avoiding the overhead of frequent thread creation and destruction. This thread pool is configured to accept multiple cross-language function call requests simultaneously and allow them to be processed in parallel by multiple threads in the pool, thereby achieving concurrent execution capabilities. Each worker thread in execution is assigned to an independent cross-language call task and is responsible for the complete lifecycle management of that task. To ensure that multiple threads do not interfere with each other when simultaneously accessing the shared memory mapping area, each thread is restricted to operating only on a specific data segment pre-allocated to its use within the shared memory. These data segments are logically or physically isolated, for example, by calculating different memory write offset addresses for each task, thereby ensuring that the target memory regions read and written by each thread do not overlap, thus maintaining data consistency and an independent execution environment for tasks.
[0064] In an optional embodiment, the task priority can be determined by a formula. Calculation determines; where, the symbol Indicates the estimated time of the task, symbol Indicates the average task time, symbol This represents the adjustment coefficient.
[0065] In this embodiment, task priority can be expressed by formula. Calculations have shown that this formula, using the Sigmoid function, maps task time differences to priority values between 0 and 1. Specifically, the estimated time for a single task... The average execution time of all tasks in the system can be estimated based on historical execution data, task type characteristics, or user-specified parameters. The adjustment coefficient can be obtained by dynamically calculating the actual execution time of tasks completed within a recent period. Used to control the steepness of the priority curve, affecting the priority difference between high-time-consuming tasks and low-time-consuming tasks. In actual scenarios, the default value can be 0.5, which can be adjusted according to the needs of the actual application scenario.
[0066] Using this priority calculation formula, the scheduler can achieve intelligent task resource allocation. Specifically, when the estimated time of a task... Greater than average time hour,( If the value is negative, the exponent term It will be greater than 1, making A value less than 0.5 indicates a relatively low priority; conversely, when the estimated time for a task is less than the average time, ( If the value is positive, the exponent term is less than 1. A value greater than 0.5 indicates a relatively high priority. This mechanism allows tasks with shorter execution times to receive higher priority, thereby reducing the system's average response time and increasing overall throughput.
[0067] In an optional embodiment, the Python client monitors the flag bits of the shared memory mapping region through an embedded execution engine, which may include:
[0068] After startup, the embedded execution engine remains resident in memory and runs an asynchronous event loop.
[0069] The asynchronous event loop continuously polls and checks the status of the flag bits in the shared memory mapping area.
[0070] When the flag is detected to be a preset set value, an independent asynchronous task is created through the asynchronous event loop to process the input data;
[0071] The asynchronous event loop continues to run after the asynchronous task is created, either processing other tasks or continuing to monitor the flag status.
[0072] In this embodiment, the Python side can monitor the flags of the shared memory mapping area through an embedded execution engine, enabling efficient data processing and task execution. Specifically, the embedded execution engine runs resident in memory after system startup and initializes the asynchronous event loop mechanism. This design avoids the overhead of starting the Python interpreter for each call, as is required in traditional methods, thereby improving system response speed and throughput.
[0073] The asynchronous event loop continuously polls to check the status changes of flags in the shared memory mapping area. When a flag is detected to be set to a preset value, it indicates that new task data has been written to the Java side. The event loop immediately creates an independent asynchronous task to process this input data. Each asynchronous task is responsible for reading, parsing the data, and executing the corresponding Python function. After processing, it writes the result back to shared memory and resets the flag. The asynchronous event loop continues to run normally after creating the asynchronous task, without being blocked, and can continue to monitor the flag status or process other task requests. This non-blocking processing mode allows the Python side to handle multiple concurrent requests simultaneously, making full use of system resources.
[0074] In an optional embodiment, the method may further include: releasing the shared memory mapping area when the system exits, wherein releasing the shared memory mapping area includes: the Java side calling a resource cleanup function on the Python side, the Python side performing a memory mapping shutdown operation, and deleting temporary files used for memory mapping.
[0075] In this embodiment, when the system triggers an exit event (such as the Java process receiving a termination instruction, the user actively closing the program, or the cleanup phase before abnormal termination), the Java side will actively call the predefined resource cleanup function on the Python side. Specifically, the Java side can send a resource release trigger signal to the Python side through an interface mechanism agreed upon by both parties, such as signal transmission based on shared memory. After receiving the resource cleanup call from the Java side, the Python side will perform a memory mapping close operation on the shared memory mapping area. Since the shared memory mapping area on the Python side is a memory segment pointer established by the mmap module or the ctypes library, the Python side will call the close method of the corresponding memory mapping object, such as the close() method of the mmap.mmap object, to release the Python runtime's holding relationship with the shared memory area, so that the operating system can reclaim the right to use the memory area, avoiding the invalid occupation of shared memory by the Python process after exiting, and preventing other processes from accidentally accessing the memory area.
[0076] Meanwhile, during the creation of the shared memory mapping region, if temporary files are used as the mapping carrier (some shared memory implementations use temporary files to construct the memory mapping region), the Python side also needs to perform a temporary file deletion operation. Specifically, the Python side will locate the storage path of these temporary files (usually located in the system temporary directory, and the filenames are pre-agreed or dynamically generated), and delete them using file operation functions (such as os.remove()). This can prevent temporary files from remaining in the file system and occupying disk space, and also prevent the creation of shared memory mapping from failing due to residual files on the next system startup.
[0077] In an optional embodiment, the Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets a flag bit, which may include:
[0078] The Java side uses a binary serialization protocol to serialize the input data;
[0079] The serialized input data is written into the data area of the shared memory mapping region;
[0080] Set a flag bit to a preset value at a predetermined location in the shared memory mapping area.
[0081] In this embodiment, the Java side receives the input data (such as an array) for the task to be processed. For complex data structures like these, a binary serialization protocol (such as MessagePack) is used for serialization. Specifically, this involves encoding input data in Java's native format (such as objects, collections, and primitive data types) into a binary byte stream, i.e., through... This operation converts input data into a cross-language compatible binary data format. This binary serialization method not only compresses data volume and reduces the time spent writing to shared memory, but also avoids format differences in text parsing between different languages, ensuring that the original data can be accurately restored during subsequent deserialization on the Python side.
[0082] After serialization, the Java side needs to write the binary byte stream to the data area of the shared memory mapping region. To ensure that the data is stored in shared memory in an ordered and non-overlapping manner, the memory write offset can be calculated using the following formula:
[0083]
[0084] Among them, symbols Indicates the starting address of shared memory, symbol Indicates the first The length of each data block can be determined using this formula. This allows us to determine the starting address of each serialized data block within the shared memory data region, thus achieving continuous and ordered data storage.
[0085] After the input data is successfully written to the data area, the Java side will set a flag to a preset value at a predetermined location in the shared memory mapping area (this location is a fixed memory address segment that is pre-agreed upon by the Java and Python sides and is independent of the data area). This preset value is a synchronization signal between the two ends. When the flag is set to this value, the Python side can recognize that the shared memory data area has stored complete input data, thereby triggering the subsequent reading and function execution process, ensuring the timing consistency of cross-language calls.
[0086] In an optional embodiment, the Java side monitors the flag bit of the shared memory mapping area. When the flag bit is detected to be reset, the execution result is read from and deserialized from the shared memory mapping area. This may include:
[0087] The Java client continuously checks the status of the flag bits of the shared memory mapping area through polling.
[0088] When the flag is detected to change from the set state to the reset state, the execution result data is read from the shared memory mapping area;
[0089] The read execution result data is deserialized to obtain the execution result of the Python function.
[0090] In this embodiment, the Java side continuously checks the status of flag bits in the shared memory mapping area through polling. Specifically, this polling method means that the Java side continuously queries the current status of the flag bits throughout the task execution cycle. Because the flag bits are signals for data interaction and synchronization between the Java and Python sides, only continuous monitoring can promptly capture the status feedback after the Python side processes the task, avoiding delays or omissions in reading execution results due to untimely monitoring. Furthermore, the polling object explicitly points to the flag bit storage area in the shared memory mapping area, ensuring that each check is of the same synchronization signal interacting with the Python side, preventing signal misalignment issues.
[0091] Next, the Java side will only read the execution result data from the shared memory mapping area when it detects that the flag's state has changed from set to reset. It's important to clarify that the flag's set state is actively set by the Java side after writing the input data of the task to be processed into shared memory, indicating that the Python side has not yet completed task processing and there is no usable execution result in shared memory at that time. The reset state, on the other hand, is modified by the Python side after completing the execution of the corresponding Python function and serializing and writing the execution result back to shared memory. This indicates that the execution result has been completely stored in shared memory, and reading at this point ensures that the obtained result data is complete and valid, avoiding incomplete or incorrect data due to premature reading.
[0092] Finally, the Java side will deserialize the execution result data read from the shared memory mapping area to obtain the execution result of the Python function.
[0093] In an optional embodiment, when multiple function execution requests are detected within a preset time window, the multiple requests are merged into a batch processing task.
[0094] The batch processing task involves unified scheduling and execution of multiple function execution requests.
[0095] The execution results of multiple functions are written back to the shared memory mapping area.
[0096] In this embodiment, the preset time window refers to a fixed time interval, such as a few milliseconds to tens of milliseconds, pre-defined for the embedded execution engine on the Python side. The specific duration is pre-configured based on the actual business's tolerance for latency. Within this time window, the embedded execution engine continuously monitors for new function execution requests (these requests all originate from cross-language call requests initiated by the Java side). When multiple independent function execution requests are received successively within this time window, a separate processing flow is not initiated for each request. Instead, these requests are integrated and packaged into a batch processing task. During the merging process, the key information of each request is fully preserved, such as the identifier of the Python function to be executed for each request and the input parameters required by the function (which have been serialized and stored in shared memory). This ensures that the independent requirements of each request can be accurately distinguished during subsequent processing, avoiding confusion of request information.
[0097] Next, once multiple requests are merged into a batch processing task, the embedded execution engine will uniformly schedule all function execution requests within this batch. During scheduling, there's no need to allocate execution resources individually for each request; instead, it allocates a continuous execution time slice to the entire batch according to the order in which the requests were received (or a preset simple priority rule; if no specific priority is specified, the order of receipt is used by default). During execution, the embedded execution engine will load the input parameters corresponding to all requests within the batch at once (read from a specified data area in the shared memory mapping region), and then sequentially call the Python function corresponding to each request, completing the function execution one by one.
[0098] Compared to executing individual requests separately, the unified scheduling and execution method in this embodiment reduces the overhead of the Python interpreter frequently switching function contexts and avoids redundant operations of repeatedly initializing the execution environment for each request, making the execution efficiency more efficient.
[0099] Once all Python functions in the batch have been executed, each function will generate its own corresponding execution result (which may be a number, a string, or complex structured data). At this point, the embedded execution engine will first organize all execution results in the order of the requests (ensuring that each result corresponds one-to-one with the original request; for example, the result of the first request corresponds to the first position in the batch, and the result of the second request corresponds to the second position, avoiding matching errors when the Java side reads them later). Then, through a single write operation, all the organized execution results will be written in batch to the preset result storage area in the shared memory mapping region.
[0100] Figure 2 This paper details the complete workflow of the cross-language execution mechanism in the technical solution of this application. The workflow can be divided into three execution phases: shared memory initialization, task execution loop, and resource cleanup. The following section, in conjunction with the appendix... Figure 2 Each stage will be explained in detail.
[0101] During the shared memory initialization phase, the system establishes a memory channel between the Java and Python runtime environments. Specifically, the Java Virtual Machine (JVM) creates a direct byte buffer instance through file channel operations. This instance is associated with a specific temporary file created in the file system and configured for read / write operations. Simultaneously, the Python interpreter uses the memory mapping module to create a corresponding memory-mapped object based on the exact same file path and memory mapping size parameters as the Java side. This series of operations, through the operating system's memory management mechanism, maps the Java-side direct byte buffer and the Python-side memory-mapped object to the same memory region, thus building the foundational shared memory channel for subsequent cross-language data interaction.
[0102] During the task execution loop phase, the system uses a loop execution mode to handle continuous cross-language call requests, such as... Figure 2 As shown, this stage comprises three execution steps. First, the Java side serializes the input data for the task to be processed. The complex object structure can be converted into compact binary data blocks using the MessagePack binary protocol. The write offset formula for each data block is used to accurately determine its write position in shared memory, ensuring that multiple consecutive data blocks are stored in an orderly manner without overlap. After successful data writing, a flag is set to a preset value at a predetermined location in shared memory, explicitly indicating the data readiness state to the Python side. Second, the embedded execution engine on the Python side runs an asynchronous event loop, continuously polling and checking the flag status changes in shared memory. When a flag is detected as ready, binary data is directly read from the memory-mapped area and deserialized. Then, an independent asynchronous task is created to execute the corresponding Python function. After the task is completed, the execution result is serialized and written back to the original data area in shared memory, while the flag is reset to its initial state. The entire process can be executed in a fully asynchronous, non-blocking manner. Finally, the Java side continuously monitors the status changes of the flag bits in the shared memory. When a flag bit is detected to be reset, the serialized result data is read from a specified location in the shared memory, and then deserialized to convert it into a data format that the Java application can directly use, thus completing the result acquisition process of this cross-language call.
[0103] During the resource cleanup phase, the system performs a complete resource reclamation operation upon termination. Specifically, when system termination is detected, the Java Virtual Machine (JVM) automatically calls the Python-side resource cleanup function through a pre-registered shutdown hook mechanism. Upon receiving the cleanup instruction, the Python interpreter performs memory mapping shutdown, releasing the occupied shared memory resources. The JVM then unmaps its own memory and deletes temporary files used for memory mapping. This bidirectional collaborative resource management mechanism in this phase ensures proper release of system resources under any runtime condition, effectively preventing issues such as memory leaks and file handle remnants.
[0104] Based on the foregoing technical solutions, this invention also provides a cross-language execution device for enabling code calls and data interaction between Java and Python language environments. From a macroscopic perspective, this device may include the following modules:
[0105] A shared memory establishment module is used to establish a shared memory mapping area between the Java and Python clients, which is accessible to both the Java and Python clients.
[0106] The Java data writing and flag setting module is used by the Java side to serialize the input data of the task to be processed and write it into the shared memory mapping area, and set the flag bit.
[0107] The Java task scheduling and thread pool management module is used by the Java side to manage the execution process of cross-language function call requests through a task scheduler and a thread pool. The task scheduler allocates threads according to task priority.
[0108] The Python data reading and execution module is used by the Python side to monitor the flag bit of the shared memory mapping area through the embedded execution engine. When the flag bit is detected to be set, the input data is read from the shared memory mapping area and deserialized, the corresponding Python function is executed, the execution result is serialized and written back to the shared memory mapping area, and the flag bit is reset.
[0109] The Java result reading and deserialization module is used to monitor the flag bit of the shared memory mapping area on the Java side. When the flag bit is detected to be reset, the execution result is read from the shared memory mapping area and deserialized.
[0110] It should be noted that the above modules are only for illustrating the technical solution of this application from a macro perspective. In the actual design of the technical solution of this application, the functional modules can be developed in other module division forms.
[0111] Figure 3 This diagram illustrates the module interactions of a possible device for implementing the cross-language execution method provided in this application embodiment in a real-world scenario. The diagram shows the module distribution and interaction between the Java runtime environment and the Python runtime environment. In the Java runtime environment, the memory interaction module is responsible for establishing connections with the shared memory mapping area, creating memory regions through DirectByteBuffer, and achieving efficient data serialization and writing operations. The task scheduling module adopts a fixed-size thread pool structure, allocating execution threads to different tasks according to the task priority calculation formula. Each thread exchanges data with the Python execution engine through an independent shared memory area.
[0112] The Python runtime environment comprises an execution engine module and a memory interaction module. The execution engine module uses an embedded Python interpreter and maintains an asynchronous event loop mechanism, capable of handling multiple concurrent requests. The Python-side memory interaction module obtains pointers to the same memory segments as the Java side via mmap or ctypes, enabling direct access to shared memory. The entire system achieves memory-level data exchange between Java and Python through shared memory mapping areas, thus avoiding the overhead of multiple data copies and serialization in traditional methods. The resource management module acts as a global resource management center, responsible for monitoring system runtime status, uniformly reclaiming memory resources, and ensuring that shared memory mappings are correctly released when the Java process exits, preventing memory leaks. This architectural design enables high-concurrency, low-latency cross-language function calls, improving the efficiency of data interaction between Java and Python.
[0113] Those skilled in the art will understand that the modules in the apparatus of the embodiments can be distributed in the apparatus of the embodiments as described in the embodiments, or they can be located in one or more devices different from this embodiment with corresponding changes. The modules of the above embodiments can be combined into one module, or they can be further divided into multiple sub-modules.
[0114] Finally, it should be noted that the above embodiments are only used to illustrate the technical solutions of the present invention, and not to limit them; although the present invention has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features; and these modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of the present invention.
Claims
1. A method for cross-language execution, used to implement code calling and data interaction between Java and Python language environments, characterized in that, Includes the following steps: Establish a shared memory mapping area between the Java client and the Python client, which is accessible to both the Java client and the Python client. The Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets a flag bit; On the Java side, a thread pool is used through a task scheduler to manage the execution process of cross-language function call requests. The task scheduler allocates threads according to task priority; wherein, the task priority is determined by the formula... Calculation determines; where, the symbol Indicates the estimated time of the task, symbol Indicates the average task time, symbol Indicates the adjustment coefficient; The Python side monitors the flags in the shared memory mapping area through an embedded execution engine. After startup, the embedded execution engine resides in memory and runs an asynchronous event loop. This asynchronous event loop continuously polls and checks the status of the flags in the shared memory mapping area. When a flag is detected to be a preset value, the asynchronous event loop creates an independent asynchronous task to process the input data. This task reads and deserializes the input data from the shared memory mapping area, executes the corresponding Python function, serializes the execution result, writes it back to the shared memory mapping area, and resets the flags. The asynchronous event loop continues to run after creating the asynchronous task, processing other tasks or continuing to monitor the flag status. The Java side monitors the flag bit of the shared memory mapping area. When it detects that the flag bit has been reset, it reads and deserializes the execution result from the shared memory mapping area.
2. The method for cross-language execution according to claim 1, characterized in that, The establishment of a shared memory mapping area between Java and Python includes: In Java, a MappedByteBuffer instance is created using the map method of FileChannel; On the Python side, the mmap module is used to create memory mappings based on the same file paths as on the Java side. The MappedByteBuffer created on the Java side and the memory-mapped object created on the Python side point to the same memory region.
3. The method for cross-language execution according to claim 1, characterized in that, The thread pool is a fixed-size thread pool, configured for multiple threads to execute concurrently, with each thread independently operating on different data regions of the shared memory mapping area.
4. The method for cross-language execution according to claim 1, characterized in that, The method further includes: when the system exits, releasing the shared memory mapping area, wherein releasing the shared memory mapping area includes: the Java side calling the resource cleanup function on the Python side, the Python side performing a memory mapping shutdown operation, and deleting the temporary files used for memory mapping.
5. The method for cross-language execution according to claim 1, characterized in that, The Java side serializes the input data of the task to be processed and writes it into the shared memory mapping area, and sets flag bits, including: The Java side uses a binary serialization protocol to serialize the input data; The serialized input data is written into the data area of the shared memory mapping region; Set a flag bit to a preset value at a predetermined location in the shared memory mapping area.
6. The method for cross-language execution according to claim 1, characterized in that, The Java side monitors the flag bit of the shared memory mapping area. When it detects that the flag bit has been reset, it reads and deserializes the execution result from the shared memory mapping area, including: The Java client continuously checks the status of the flag bits of the shared memory mapping area through polling. When the flag is detected to change from the set state to the reset state, the execution result data is read from the shared memory mapping area; The read execution result data is deserialized to obtain the execution result of the Python function.
7. The method for cross-language execution according to claim 1, characterized in that, When multiple function execution requests are detected within a preset time window, the multiple requests are merged into a batch processing task; The batch processing task involves unified scheduling and execution of multiple function execution requests. The execution results of multiple functions are written back to the shared memory mapping area.
8. An apparatus for cross-language execution using any one of the cross-language execution methods of claims 1-7, for implementing code calls and data interaction between Java and Python language environments, characterized in that, Includes the following modules: A shared memory establishment module is used to establish a shared memory mapping area between the Java and Python clients, which is accessible to both the Java and Python clients. The Java data writing and flag setting module is used by the Java side to serialize the input data of the task to be processed and write it into the shared memory mapping area, and set the flag bit. The Java task scheduling and thread pool management module is used by the Java side to manage the execution process of cross-language function call requests through a task scheduler and a thread pool. The task scheduler allocates threads according to task priority. The Python data reading and execution module is used by the Python side to monitor the flag bit of the shared memory mapping area through the embedded execution engine. When the flag bit is detected to be set, the input data is read from the shared memory mapping area and deserialized, the corresponding Python function is executed, the execution result is serialized and written back to the shared memory mapping area, and the flag bit is reset. The Java result reading and deserialization module is used to monitor the flag bit of the shared memory mapping area on the Java side. When the flag bit is detected to be reset, the execution result is read from the shared memory mapping area and deserialized.
Citation Information
Patent Citations
Interprocess function invocation method and device based on shared memory
CN107491355A
A method for quickly sharing image memory across languages in a visual servo system
CN109542649A