Concurrent control method, device, storage medium and program product for lock-free ring buffer
Patent Information
- Application Number
- CN202611128088.4
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-07-28
- Publication Date
- 2026-10-27
AI Technical Summary
然而,随着处理器核心数量激增,基于单一全局原子变量进行指针移动的方案面临显著性能瓶颈
[0009]本申请实施例的技术方案中,通过响应于多个生产者对无锁环形缓冲区的写入操作,通过原子操作竞争将写指针从第一值更新至第二值,并递增全局生产者序列号;响应于多个消费者对无锁环形缓冲区的读取操作,读取全局生产者序列号和全局消费者序列号;基于全局生产者序列号和全局消费者序列号判断是否对无锁环形缓冲区进行读取操作,当确定进行操作时,通过原子操作竞争将读指针从第三值更新至第四值,并递增全局消费者序列号;如此,通过在无锁环形缓冲区中同时维护全局生产者序列号和全局消费者序列号两个独立序列号,解决ABA问题的同时避免全局序列号的性能瓶颈,对比传统单序列号方案可以大幅减少原子操作冲突率。
Smart Images

Figure CN122985108A_ABST
Abstract
Description
Technical Field
[0001] This application relates to cloud computing technology and cloud networking, and in particular to a method, device, storage medium, and program product for concurrent control of a lockless circular buffer. Background Technology
[0002] Currently, high-performance servers are commonly deployed on multi-core processor platforms to handle a large number of business requests in a high-concurrency mode. As a basic synchronization method to ensure the consistency of access to shared resources among multiple threads / processes, locking mechanisms inherently suffer from blocking and context switching overhead, which significantly impairs system throughput under high concurrency contention and easily introduces response latency.
[0003] Therefore, existing technologies propose lock-free circular buffers, which use atomic operations to move two key pointers to achieve data reading and writing, avoiding lock contention while maintaining cache locality. However, with the surge in the number of processor cores, schemes based on pointer movement using a single global atomic variable face significant performance bottlenecks. Furthermore, in multi-producer, multi-consumer scenarios, the high-frequency operations on shared variables by multiple threads lead to increased atomic operation conflict rates and cache line misses, resulting in a significant decrease in effective bandwidth and throughput. Summary of the Invention
[0004] To address the aforementioned issues, embodiments of this application provide a method, device, storage medium, and program product for concurrent control of a lockless circular buffer.
[0005] In a first aspect, the concurrency control method for a lock-free circular buffer provided in the embodiments of this application includes: In response to multiple write operations to the lockless circular buffer, the write pointer is updated from a first value to a second value through atomic operation competition, and the global producer sequence number is incremented; In response to multiple consumers' read operations on the lock-free circular buffer, the global producer sequence number and the global consumer sequence number are read. Based on the global producer sequence number and the global consumer sequence number, it is determined whether to perform a read operation on the lock-free circular buffer. When it is determined to perform the operation, the read pointer is updated from the third value to the fourth value through atomic operation competition, and the global consumer sequence number is incremented.
[0006] Secondly, the electronic device provided in the embodiments of this application includes: a processor and a memory, the memory being used to store a computer program, and the processor being used to call and run the computer program stored in the memory to execute any of the above-described lockless circular buffer concurrency control methods.
[0007] Thirdly, the computer-readable storage medium provided in the embodiments of this application is used to store a computer program that causes a computer to execute any of the above-described lockless circular buffer concurrency control methods.
[0008] Fourthly, the computer program product provided in the embodiments of this application includes computer program instructions that cause a computer to execute any of the above-described lockless circular buffer concurrency control methods.
[0009] In the technical solution of this application embodiment, in response to multiple producers' write operations on the lock-free circular buffer, the write pointer is updated from a first value to a second value through atomic operation competition, and the global producer sequence number is incremented; in response to multiple consumers' read operations on the lock-free circular buffer, the global producer sequence number and the global consumer sequence number are read; based on the global producer sequence number and the global consumer sequence number, it is determined whether to perform a read operation on the lock-free circular buffer. When it is determined to perform an operation, the read pointer is updated from a third value to a fourth value through atomic operation competition, and the global consumer sequence number is incremented; thus, by maintaining two independent sequence numbers, the global producer sequence number and the global consumer sequence number, in the lock-free circular buffer, the ABA problem is solved while avoiding the performance bottleneck of the global sequence number. Compared with the traditional single sequence number scheme, the atomic operation conflict rate can be significantly reduced. Attached Figure Description
[0010] Figure 1 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 1 ; Figure 2 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 2 ; Figure 3 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 3 ; Figure 4 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 4 ; Figure 5 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 5 ; Figure 6 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 6 ; Figure 7 This is a flowchart illustrating a concurrency control method for a lockless circular buffer provided in an embodiment of this application. Figure 7; Figure 8 This is a schematic diagram of the structure of a concurrent control device for a lockless circular buffer provided in an embodiment of this application; Figure 9 This is a schematic structural diagram of an electronic device provided in an embodiment of this application.
[0011] It should be noted that the terms "first" and "second" mentioned above are only used to distinguish between different options and do not represent the degree of superiority or inferiority of the options or their priority in the implementation process. Detailed Implementation
[0012] To make the objectives, technical solutions, and advantages of this application clearer, the application will be further described in detail below with reference to the accompanying drawings. The described embodiments should not be regarded as limitations on this application. All other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of this application.
[0013] In the following description, references are made to “some embodiments,” which describe a subset of all possible embodiments. However, it is understood that “some embodiments” may be the same subset or different subsets of all possible embodiments and may be combined with each other without conflict.
[0014] In the following description, the terms "first, second, third" are used merely to distinguish similar objects and do not represent a specific ordering of objects. It is understood that "first, second, third" may be interchanged in a specific order or sequence where permitted, so that the embodiments of this application described herein can be implemented in an order other than that illustrated or described herein.
[0015] Unless otherwise defined, all technical and scientific terms used in the embodiments of this application have the same meaning as commonly understood by one of ordinary skill in the art. The terminology used in the embodiments of this application is for the purpose of describing the embodiments of this application only and is not intended to limit this application.
[0016] Before providing a further detailed description of the embodiments of this application, the nouns and terms involved in the embodiments of this application will be explained, and the nouns and terms involved in the embodiments of this application shall be interpreted as follows.
[0017] 1) Linux kernel's kfifo: kfifo is a general-purpose, high-efficiency first-in-first-out (FIFO) byte stream buffer implemented in the Linux kernel. It uses a circular queue data structure at the underlying level, enabling concurrent operations between two threads in a single-producer, single-consumer (1P1C) scenario without the need for locking. kfifo requires the buffer size to be a power of 2 so that bitwise operations can replace modulo operations to improve performance.
[0018] 2) Lock-free circular buffer: A lock-free circular buffer is a concurrent data structure that uses a circular queue as its underlying storage model. The buffer maintains read and write pointers, indicating the current readable and writable data positions, respectively. When a data element is consumed, the remaining data elements do not need to be moved, thus reducing data copying and improving efficiency. In the lock-free implementation, producers and consumers move pointers atomically, avoiding the use of traditional locking mechanisms for synchronization.
[0019] 3) Atomic Operations: An atomic operation is an operation that cannot be interrupted, disrupted, or interfered with by other operations in a concurrent environment. All actions within an atomic operation are either all executed or none are executed; it is an indivisible basic unit of execution. Atomic operations are a crucial foundation for ensuring consistency and synchronization of shared resource access in multi-threaded or multi-process environments, and a key underlying mechanism for constructing lock-free data structures. In this embodiment, an atomic operation can be a Compare and Set (CAS) operation. The logic of a CAS operation is to atomically perform the following judgment: The value of V is updated to the new value B only if and only if the current value of memory location V equals the expected value A; otherwise, no update is performed. Regardless of whether the operation is successful, it typically returns the value of the memory location before the update, allowing the caller to determine whether the operation was successful.
[0020] 4) Producer-Consumer: The Producer-Consumer model is a classic concurrency control model in multithreaded programming. In this model, the party that produces data is called the producer, and the party that processes the data is called the consumer. Producers and consumers exchange data through a buffer; the producer puts data into the buffer, and the consumer retrieves data from the buffer for processing. This model is used to coordinate data access between multiple threads, prevent race conditions, and improve the program's concurrency capabilities.
[0021] 5) Non-Uniform Memory Access (NUMA) Nodes: NUMA nodes are a multiprocessor memory architecture model. In this architecture, system hardware resources are divided into multiple groups, each group being called a NUMA node. Each node contains several CPU cores, an independent integrated memory controller, and local physical memory. CPU access to local memory within its own node is much faster than accessing remote memory on other nodes.
[0022] 6) The ABA problem in a lockless circular buffer manifests as follows: Consumer 1 reads the data at position A and is then suspended. Other consumers quickly consume the data at position A and reuse the slot in a loop (A→B→A). When Consumer 1 resumes and executes CAS, it finds that the read pointer still points to A and mistakenly assumes that the data has not changed, leading to duplicate consumption and memory access conflicts.
[0023] In existing technologies, high-performance server software mostly runs on multi-core servers. Most current hardware can provide 32, 64, or even more CPUs for concurrent data processing. In such high-concurrency business scenarios, locks are the core mechanism for controlling resource access and ensuring data consistency. They ensure that only one thread / process can access critical resources (such as database rows, memory variables, files, etc.) at a time. However, locks also have significant side effects, often impairing system performance. To address these issues, existing technologies propose using the Linux kernel's kfifo lock-free circular buffer. This buffer employs a classic circular queue structure and uses two key pointers for efficient data transfer: a read pointer indicating the starting position of currently readable data in the buffer, and a write pointer indicating the starting position of currently writable data. By moving these two pointers atomically, the system can achieve concurrent data read and write operations without locking. KFIFO not only supports the single-producer, single-consumer model but also extends to support multi-producer, single-consumer scenarios. By avoiding lock contention, it achieves high throughput, extremely low latency data transfer, and optimizes memory access locality, demonstrating significant performance advantages. It plays a crucial role in high-performance data forwarding scenarios such as network protocol stacks (e.g., TCP / IP protocol processing) and device drivers (high-speed data acquisition). However, existing technologies suffer from two main limitations. Firstly, they lack sufficient protection against the ABA problem. The absence of sequence number marking or reliance solely on pointer value comparison fails to identify intermediate state changes, potentially leading to memory safety or data consistency issues. Secondly, their applicability is limited. Existing Linux KFIFO models are poorly optimized for multi-producer, multi-consumer scenarios. In multi-threaded environments, competition between producers and consumers for the same sequence number and head / tail pointers results in a CAS conflict rate exceeding 60% with 32 threads. Frequent cache line invalidation reduces effective bandwidth by approximately 70%, significantly decreasing throughput.
[0024] To address the aforementioned issues, embodiments of this application provide a lock-free circular buffer concurrency control method, electronic device, and computer-readable storage medium. This method can solve the ABA problem while avoiding the performance bottleneck of global serial numbers, and can significantly reduce the CAS conflict rate compared to traditional single-serial-number schemes.
[0025] To facilitate understanding of the technical solutions of the embodiments of this application, the technical solutions of this application are described in detail below through specific embodiments. The above-mentioned related technologies are optional solutions and can be arbitrarily combined with the technical solutions of the embodiments of this application, all of which fall within the protection scope of the embodiments of this application. The embodiments of this application include at least some of the following contents.
[0026] See Figure 1 , Figure 1 This is a flowchart illustrating a lock-free circular buffer concurrency control method provided in this application embodiment. The execution subject of this method is an electronic device, which can specifically be a tablet computer, laptop computer, ultra-mobile personal computer (UMPC), etc. This application embodiment does not impose any restrictions on the specific type of electronic device. The concurrency control method will combine... Figure 1 The steps shown are explained below: In step 101, in response to multiple producers' write operations on the lock-free circular buffer, the write pointer is updated from the first value to the second value through atomic operation competition, and the global producer sequence number is incremented.
[0027] In this embodiment, a lock-free circular buffer is used as a data structure to store data sent and received during communication. The lock-free circular buffer is a first-in-first-out (FIFO) circular buffer that provides mutual exclusion access to the buffer for the communication program.
[0028] In some embodiments, the lock-free circular buffer includes a first read pointer and a first write pointer. The first write pointer indicates the index variable of the next data slot in the lock-free circular buffer that can be used for writing, and it advances cyclically within the buffer. The first write pointer can also be called the head pointer; moving the first write pointer enables data writing to the lock-free circular buffer. The first read pointer indicates the index variable of the next data slot in the lock-free circular buffer that can be used for reading, and it consumes data cyclically within the buffer. The first read pointer can also be called the tail pointer; moving the first read pointer enables data reading from the lock-free circular buffer.
[0029] In this embodiment, the atomic operation includes an atomic compare-and-swap (CAS) operation. The CAS operation compares the value at a certain memory location with a given old value. If they are equal, the value at that location is replaced with the new value; otherwise, no replacement is performed. When multiple producer threads concurrently generate data that needs to be written to the circular buffer, each producer thread first atomically loads the current value of the write pointer, denoted as the first value. Then, based on the expected number of slots to be reserved (which can be one or more), the next target value of the head pointer is calculated, denoted as the second value. The atomic compare-and-swap (CAS) operation attempts to update the write pointer from the first value to the second value.
[0030] In some embodiments, the result of an atomic operation competition includes competition success and competition failure; when the atomic operation competition result is competition success, the write pointer is updated from the first value to the second value; when the atomic operation competition result is competition failure, the atomic operation is retried after exponential backoff.
[0031] Here, for multiple producer threads competing simultaneously, only one thread can successfully execute the CAS operation, thus atomically acquiring exclusive write access to the corresponding data slot. The producer thread that successfully reserves the slot writes the data to the slot memory. The producer thread that fails to reserve the slot reloads the new value of the write pointer after exponential backoff and retryes the above process.
[0032] In some embodiments, the lock-free circular buffer includes multiple data slots, each data slot having a slot sequence number. After updating the head pointer from a first value to a second value through an atomic operation competition, the method further includes: reserving at least one data slot; writing the data to be written to the reserved data slot; reading the current global producer sequence number; and writing the current global producer sequence number to the slot sequence number corresponding to the reserved data slot.
[0033] Here, the global producer sequence number is a monotonically increasing global counter that records the total number of times a producer has successfully written data items. It increments after each write operation to indicate the data production progress. For multiple producer threads competing simultaneously, the producer thread that successfully reserves a slot writes the data to the slot memory, then writes the current global producer sequence number to the slot sequence number field using release semantics, and atomically increments the global producer sequence number.
[0034] For example, see Figure 2 , Figure 2This is a flowchart illustrating a multi-producer concurrent access to a lock-free circular buffer provided in an embodiment of this application. When multiple producer threads concurrently generate data that needs to be written to the circular buffer, each producer thread first atomically loads the current value of the write pointer, denoted as the first value, as shown in the figure: head:0. Then, based on the expected number of slots to be reserved (which can be one or more), the next target value of the head pointer is calculated, denoted as the second value, as shown in the figure: head:1. An atomic Compare And Swap (CAS) operation is then used to attempt to update the head pointer from the first value to the second value (e.g., CAS(head:0→1)). For multiple competing producer threads, only one thread can successfully execute the CAS operation (e.g., ...). Figure 2 Producer 1 successfully executes CAS (head:0→1), thus atomically acquiring exclusive write access to the corresponding data slot. Producer threads that successfully reserve slots write data to the slot memory, i.e., write buffer[0]=data1, then write the current global producer sequence number to the slot sequence number field using release semantics, and atomically increment the global producer sequence number (producer_seq++). Producer threads that fail to reserve slots (such as...) Figure 2 Producer 2) reloads the new value of the head pointer after exponential backoff (rereads head=1) and retryes the above process. It executes CAS (head:1→2) successfully, writes buffer[1]=data2, and then atomically increments the global producer sequence number (producer_seq++).
[0035] In this embodiment of the application, multiple producers are grouped according to non-consistent memory access NUMA nodes, and each NUMA node includes a second write pointer and a second read pointer.
[0036] In some embodiments, each producer performs a local atomic operation on the second write pointer of its NUMA node; and / or each consumer performs a local atomic comparison-swap operation on the second read pointer of its NUMA node; and according to the synchronization triggering condition, the progress of the second write pointer and / or the second read pointer of the NUMA node is updated in batches to the first write pointer and / or the first read pointer through a global atomic comparison-swap operation.
[0037] See here. Figure 3 This application proposes a lock-free circular buffer concurrency control method suitable for NUMA architecture. By grouping producers by NUMA nodes and configuring a second write pointer local_head for each group, global competition is decomposed into intra-node competition and controllable cross-node synchronization, thereby significantly reducing atomic operation conflicts and improving system throughput.
[0038] For example, multiple producer threads are grouped by NUMA nodes, and each NUMA node group is assigned a separate second write pointer, with each pointer aligned to a cache line. In a multi-processor server system, there are significant differences in latency between accessing local and remote memory by different processor cores. The system first identifies the NUMA nodes that each producer thread is affinity-to and assigns the threads to the corresponding node groups. Each node group is assigned a separate second write pointer (i.e., a local head pointer), which occupies a separate memory space in memory for the size of a processor cache line (typically 64 bytes) and is initially aligned to a cache line. Meanwhile, the circular buffer body, the global first write pointer (i.e., the global head pointer), the first read pointer (i.e., the global tail pointer), and the data and sequence numbers for each slot are all stored in shared memory accessible to all nodes. It should be noted that each node can also be assigned a second read pointer (i.e., a local tail pointer) for implementing similar localized contention optimizations on the consumer side.
[0039] For example, each producer performs a local CAS operation on the second write pointer of its NUMA node to modify the second write pointer in order to reserve data slots. When a producer thread generates data to be written, it no longer directly competes for the global first write pointer, but instead prioritizes the second write pointer of its own node group. Specifically, the producer atomically loads the current value of its node's second write pointer and calculates the target value corresponding to the expected number of consecutive slots N (N≥1) to be reserved in this batch; then, it attempts to update the second write pointer from the current value (first value) to the target value (second value) through a CAS operation. If the CAS succeeds, the producer obtains exclusive access to write data to the buffer for N consecutive slots within its local progress range; if the CAS fails, it means that another producer within the same node has preemptively reserved the slots. The producer can retry using an exponential backoff strategy, or, if consecutive failures exceed a threshold, attempt to migrate to the second write pointer of a neighboring node or directly trigger global synchronization. After obtaining the slots, the producer writes the data and updates the slot sequence number and the global producer sequence number accordingly. Thus, by reducing the scope of contention from all threads globally to threads within a single NUMA node, both the probability of CAS conflicts and cross-node cache consistency traffic are significantly reduced.
[0040] For example, after a successful CAS operation, based on the synchronization triggering condition, the progress of the second write pointer of the NUMA node is updated to the first write pointer `global_head` in batches through a global atomic operation. When any condition is met, the global synchronization process is triggered: the latest local progress indicated by the second write pointer of each NUMA node is collected, and the global first write pointer is updated to the minimum value (or cumulative value) of the progress of all nodes through a global atomic comparison and exchange operation, thereby publishing the slots that have been reserved locally and completed to a globally visible state in batches.
[0041] In some embodiments, the synchronization triggering conditions include one or more of the following: the node local operation count reaches a first preset threshold, the consumer's NUMA node is detected to be different from the producer's NUMA node, the used space of the lockless circular buffer exceeds a preset proportion, and the number of retries reaches a second preset threshold.
[0042] Here, the node local operation count reaches a first preset threshold, including the producer thread's local write operation count reaching a preset interval (e.g., every 100 writes completed); the NUMA node where the consumer is located is detected to be different from the NUMA node where the producer is located, including the NUMA node detecting that the consumer's NUMA node is different from the producer's, such as the current access latency exceeding a preset threshold; the used space of the lock-free circular buffer exceeds a preset proportion, including when the used space proportion of the circular buffer is detected to exceed a preset value (e.g., 80%), global synchronization is immediately performed to prevent the producer from over-leading.
[0043] Furthermore, the system can dynamically adjust the synchronization interval or counting threshold according to the current load, increasing the interval under low load to reduce atomic operation overhead, and decreasing the interval under high load to ensure the timeliness of data visibility to consumers.
[0044] After global synchronization is completed, each node producer continues to compete for new write requests based on its local second write pointer, and so on in a loop.
[0045] In other embodiments, when the number of retries reaches a second preset threshold, the producer and / or consumer are migrated to a nearby NUMA node.
[0046] Here, when the producer and / or consumer retry multiple times and reach the second preset threshold, such as more than 10 consecutive failures, they can migrate to the local write pointer of the neighboring NUMA node to continue trying.
[0047] Thus, this embodiment transforms the intense competition among multiple producers for a single global pointer into a two-stage process: first, low-cost competition for the local second write pointer within each NUMA node; and then, based on a strategy, batch merging the local progress into the global first write pointer. By reducing the competition domain from N threads globally to N / M threads within each node (where M is the number of nodes), the probability of CAS conflicts is significantly reduced, effectively avoiding cross-node cache line conflicts. Simultaneously, by employing batch global synchronization, the publication of multiple slots consumes only one global atomic operation, significantly reducing the number of global synchronizations. Combined with a dynamically adjustable synchronization triggering strategy, the system can minimize atomic operation overhead under light loads and ensure low-latency visibility under high loads, thereby achieving an overall throughput increase of several times and excellent scalability.
[0048] In step 102, in response to multiple consumers' read operations on the lock-free circular buffer, the global producer sequence number and the global consumer sequence number are read.
[0049] In this embodiment, each consumer thread first obtains the current value of the global producer sequence number and the current value of the global consumer sequence number before attempting to retrieve data. This ensures that all memory access instructions following the read operation are not reordered before the read operation, thereby guaranteeing that the consumer can observe the latest data status published by the producer.
[0050] In this embodiment, the global consumer sequence number refers to a monotonically increasing global counter that records the total number of data items that the consumer has successfully read and processed. The counter increments after each consumption to indicate the data consumption progress.
[0051] In some embodiments, the current values of the global producer sequence number and the global consumer sequence number are loaded from shared memory using acquire semantics. Acquire semantics is a memory ordering constraint that stipulates that all read and write operations after this operation cannot be executed beforehand, and is used to read shared state to establish synchronization and visibility relationships between threads.
[0052] In step 103, it is determined whether to perform a read operation on the lock-free circular buffer based on the global producer sequence number and the global consumer sequence number. When it is determined to perform the operation, the tail pointer is updated from the third value to the fourth value through atomic operation competition, and the global consumer sequence number is incremented.
[0053] In some embodiments, determining whether to perform a read operation on the lock-free circular buffer based on the global producer sequence number and the global consumer sequence number includes: determining whether the global producer sequence number and the global consumer sequence number are equal; if they are equal, determining not to perform the operation; if they are not equal, reading the slot sequence number of the target slot pointed to by the current tail pointer; determining whether the slot sequence number is equal to the global producer sequence number; if they are not equal, determining not to perform the operation; if they are equal, determining to perform the operation.
[0054] See here. Figure 4The consumer thread first compares the read global producer sequence number with the global consumer sequence number. If they are equal, it indicates that no producer has published new data that has not yet been consumed. In this case, the consumer can adopt strategies such as spin-waiting or yielding the CPU and not perform further operations. If they are not equal, it is determined that there is data to be consumed, and a read operation is required. To avoid the ABA problem, the consumer further performs a validity check: it reads the pre-stored slot sequence number in the target data slot pointed to by the current read pointer and compares it with the current global consumer sequence number. Only when they match is it considered that the data in that slot is valid new data, and has not been preemptively consumed by other consumers or overwritten by producers in a loop. After passing the above check, the consumer performs a CAS operation, attempting to atomically update the read pointer from the current value (third value) to the next position (fourth value).
[0055] In some embodiments, the lock-free circular buffer includes a first read pointer, which indicates the index variable of the next available data slot in the lock-free circular buffer, and is consumed cyclically within the buffer. The first read pointer can also be called a tail pointer; data reading from the lock-free circular buffer can be achieved by moving the first read pointer.
[0056] In this embodiment, the atomic operation includes an atomic compare-and-swap (CAS) operation. The CAS operation compares the value at a certain memory location with a given old value. If they are equal, the new value replaces the value at that location; otherwise, no replacement is performed. When multiple consumer threads concurrently generate data that needs to be read from the circular buffer, each consumer thread first atomically loads the current value of the read pointer, denoted as the third value. Then, it attempts to update the read pointer from the third value to the target value, i.e., the fourth value, using a CAS operation.
[0057] In some embodiments, the result of an atomic operation competition includes a competition success and a competition failure; when the atomic operation competition result is a competition success, the write pointer is updated from a first value to a second value, and / or the read pointer is updated from a third value to a fourth value; when the atomic operation competition result is a competition failure, the atomic operation is retried after exponential backoff.
[0058] Here, for multiple consumer threads competing simultaneously, only one thread can successfully execute the CAS operation, thus atomically acquiring exclusive read access to the corresponding data slot. The successful consumer thread reads the data from the target slot. The consumer thread that fails to read the data reloads the new value of the read pointer after exponential backoff and retryes the above process.
[0059] For example, see Figure 5 , Figure 5This is a flowchart illustrating a multi-consumer concurrent access to a lock-free circular buffer provided in an embodiment of this application. The consumer thread first compares the read global producer sequence number with the global consumer sequence number. If they are equal, it indicates that no producer has published new data that has not yet been consumed. In this case, the consumer can adopt strategies such as spin-waiting or yielding the CPU and not perform further operations. If they are not equal, it is determined that there is data to be consumed, and a read operation is required. To avoid the ABA problem, the consumer further performs a validity check: it reads the pre-stored slot sequence number in the target data slot pointed to by the current read pointer and compares it with the current global consumer sequence number. Only when they match is it indicated that the data in the slot is valid new data, and has not been preemptively consumed by other consumers or overwritten by producers in a loop. After passing the above check, the consumer performs a CAS operation, attempting to atomically update the read pointer from the current value (third value) to the next position (fourth value). Consumer threads that succeed in CAS acquire the data in the slot and atomically increment the global consumer sequence number after reading, declaring consumption complete; threads that fail in CAS re-execute the competition process starting from loading the read pointer.
[0060] In this embodiment, multiple consumers are grouped according to non-consistent memory access NUMA nodes, and each NUMA node includes a second write pointer and a second read pointer.
[0061] In some embodiments, each producer performs a local atomic operation on the second write pointer of its NUMA node; and / or each consumer performs a local atomic comparison-swap operation on the second read pointer of its NUMA node; and according to the synchronization triggering condition, the progress of the second write pointer and / or the second read pointer of the NUMA node is updated in batches to the first write pointer and / or the first read pointer through a global atomic comparison-swap operation.
[0062] This application proposes a lock-free circular buffer concurrency control method suitable for NUMA architecture. By grouping consumers by NUMA nodes and configuring local read pointers for each group, global competition is decomposed into intra-node competition and controllable cross-node synchronization, thereby significantly reducing atomic operation conflicts and improving system throughput.
[0063] For example, multiple consumer threads are grouped by NUMA nodes, each NUMA node group is assigned a separate second read pointer, and these pointers are aligned to cache lines. In multi-processor server systems, there are significant differences in latency between accessing local and remote memory by different processor cores. The system first identifies the NUMA nodes that each consumer thread is affinity-to and assigns the threads to the corresponding node groups. Each node group is assigned a separate second read pointer (i.e., a local tail pointer), which occupies a separate memory space in memory according to the processor cache line size (typically 64 bytes) and is initially aligned to a cache line. Meanwhile, the circular buffer body, the global first write pointer (i.e., the global head pointer), the first read pointer (i.e., the global tail pointer), and the data and sequence numbers of each slot are all stored in shared memory accessible to all nodes. It should be noted that each node can also be assigned a second write pointer (i.e., a local head pointer) for similar localized contention optimizations on the producer side.
[0064] For example, each consumer performs a local atomic operation on the second read pointer of its NUMA node to read data from the target slot. When a consumer thread is ready to read data, it no longer directly competes for the global first read pointer, but instead prioritizes the second read pointer of its own node group. See details. Figure 6 The consumer atomically loads the current value of the second read pointer of its local node (i.e., reads tail=0). Then, it attempts to update the second read pointer from its current value (the third value) to the target value (the fourth value) using a CAS operation. If the CAS succeeds (i.e., CAS(0→1) succeeds), the consumer obtains the data in the target slot. If the CAS fails, it indicates that another consumer within the same node has preemptively read the data. This consumer can retry using an exponential backoff strategy, or, if consecutive failures exceed a threshold, attempt to migrate to the second write pointer of a neighboring node or directly trigger global synchronization. After reading the data in the target slot, the consumer updates the global consumer sequence number (i.e., atomically increments consumer_seq) to mark the completion of data consumption. Thus, by reducing the scope of contention from all threads globally to threads within a single NUMA node, the probability of CAS conflicts and cross-node cache consistency traffic are significantly reduced.
[0065] For example, based on the synchronization trigger condition, the progress of the second read pointer of the NUMA node is updated to the first read pointer in batches through a global atomic operation. When any condition is met, the global synchronization process is triggered: the latest local progress indicated by the second read pointer of each NUMA node is collected, and the global first read pointer is updated to the minimum value (or cumulative value) of the progress of all nodes through a global atomic comparison and exchange operation, thereby publishing the slots that have been reserved locally and read to the global visible state in batches.
[0066] In some embodiments, the synchronization triggering conditions include one or more of the following: the node local operation count reaches a first preset threshold, the NUMA node where the consumer is located is different from the NUMA node where the producer is located, the used space of the lockless circular buffer exceeds a preset proportion, and the number of retries reaches a second preset threshold.
[0067] Here, the node local operation count reaches a first preset threshold, including the consumer thread's local write operation count reaching a preset interval (e.g., every 100 writes completed); the NUMA node where the consumer is located is detected to be different from the NUMA node where the producer is located, including the NUMA node detecting that the consumer's NUMA node is different from the producer's, such as the current access latency exceeding a preset threshold; the used space of the lock-free circular buffer exceeds a preset proportion, including when the used space proportion of the circular buffer is detected to exceed a preset value (e.g., 80%), global synchronization is immediately performed to prevent the producer from over-leading.
[0068] Furthermore, the system can dynamically adjust the synchronization interval or counting threshold according to the current load, increasing the interval under low load to reduce atomic operation overhead, and decreasing the interval under high load to ensure the timeliness of data visibility to consumers.
[0069] After global synchronization is completed, each node consumer continues to compete for new read requests based on its local second read pointer, and so on in a loop.
[0070] In other embodiments, when the number of retries by producers and / or consumers reaches a second preset threshold, producers and / or consumers are migrated to a nearby NUMA node.
[0071] Here, when the producer and / or consumer retry multiple times and reach the second preset threshold, such as more than 10 consecutive failures, they can migrate to the local pointer of a neighboring NUMA node to continue trying.
[0072] Thus, this embodiment transforms the intense competition among multiple consumers for a single global pointer into a two-stage process: first, low-cost competition for the local second read pointer within each NUMA node; and then, batch merging of local progress into the global first read pointer according to a strategy. By reducing the competition domain from N threads globally to N / M threads within each node (M being the number of nodes), the probability of CAS conflicts is significantly reduced, effectively avoiding cross-node cache line conflicts. Simultaneously, the use of batch global synchronization means that publishing multiple slots consumes only one global atomic operation, significantly reducing the number of global synchronizations. Combined with a dynamically adjustable synchronization triggering strategy, the system can minimize atomic operation overhead under light loads and ensure low-latency visibility under high loads, thereby achieving an overall throughput increase of several times and excellent scalability.
[0073] Example 1 See Figure 7 , Figure 7 This is a flowchart illustrating a multi-producer, multi-consumer concurrent access to a lock-free circular buffer provided in this application embodiment. Specifically, this embodiment uses a specific concurrent scenario where two producer threads simultaneously write data and two consumer threads simultaneously read data as an example to further illustrate the process of the lock-free circular buffer concurrency control method described in the aforementioned embodiment. Initially, the circular buffer is empty, with head pointer head=0, tail pointer tail=0, global producer sequence number producer_seq=0, global consumer sequence number consumer_seq=0, and the slot sequence number field for each slot is invalid.
[0074] Concurrent producer write process: Producer 1 and Producer 2 write data simultaneously, competing for the header pointer through an atomic compare-and-swap (CAS) operation. Only Producer 1's CAS operation succeeds; Producer 2 must retry to ensure that the producer that successfully retrieves data updates the global producer sequence number after a successful CAS operation. The specific steps are as follows.
[0075] 1. Producer 1 loads head=0, tail=0.
[0076] Here, `head=0` indicates that the currently writable slot index of the circular buffer is 0; `tail=0` indicates that the currently readable slot index is also 0, and the buffer is currently empty. Producer 1 uses atomic loading to read `head` and `tail` to obtain the current buffer state, which is then used to subsequently check whether the buffer is full (e.g., checking `global_head - slowest_tail` > `size`). 0.8).
[0077] 2. Producer 2 loads head=0, tail=0.
[0078] Here, producer 2 executes concurrently with producer 1, and both are atomically loaded to obtain the same head=0 and tail=0, sharing the same initial view of the buffer.
[0079] 3. Producer 1 successfully performed a CAS (0→1) operation and wrote element data1.
[0080] Here, producer 1 performs an atomic compare-and-swap operation, updating the head pointer from 0 to 1, atomically reserving the slot corresponding to index 0. A successful CAS operation means producer 1 has acquired exclusive write rights to that slot. Producer 1 writes the data 'data1' into the memory of buffer slot 0, then releases the current global producer sequence number (producer_seq=0) into the slot sequence number field of that slot using release semantics, and finally atomically increments the global producer sequence number from 0 to 1. The slot sequence number is now recorded as 0, a value the consumer will use to verify the data version.
[0081] 4. Producer serial numbers increment.
[0082] Here, the global producer sequence number is incremented from 0 to 1, signifying that a data item has been successfully produced and assigning it a unique time-series identifier. The incremented producer sequence number can then be used by consumers to detect the generation of new data.
[0083] 5. Producer 2's CAS (0→1) failed, retry.
[0084] Here, producer 2 attempts to update head from 0 to 1 using CAS (Compare-and-Swap), but since head has already been modified to 1 by producer 1, the CAS comparison phase finds that the current value is not equal to the expected value of 0, and the operation fails. This result informs producer 2 of the existence of a race condition, and triggers the retry mechanism.
[0085] 6. Producer 2 reloads head=1.
[0086] Here, producer 2 atomically reloads the latest value of head during the retry, resulting in head=1, indicating that index 1 is the next writable slot. During the retry process, the buffer can also be checked to see if it is full.
[0087] 7. Producer 2 successfully performed a CAS (1→2) and wrote element data2.
[0088] Here, producer 2 performs a new CAS operation, attempting to update head from 1 to 2, successfully reserving slot 1. It then writes data2 into that slot, writes the current global producer sequence number (producer_seq=1 at this point) into the sequence number field of slot 1, and then increments the global producer sequence number.
[0089] 8. Producer serial numbers increment.
[0090] Here, the global producer sequence number increments from 1 to 2, indicating that the second data item has been produced.
[0091] Consumer concurrent read process: At this point, the circular buffer already contains two data items, data1 and data2, with head=2 and tail=0. Consumer 1 and Consumer 2 simultaneously attempt to read data. Before executing the CAS operation to compete for the tail pointer, both consumers have already acquired the global producer sequence number and the global consumer sequence number using acquire semantics. They confirm that the producer sequence number is not equal to the global consumer sequence number, and each consumer verifies that the slot sequence number pointed to by the current tail pointer matches the global consumer sequence number to avoid the ABA problem. The specific steps are as follows.
[0092] 1. Consumer 1 loads tail=0, head=2.
[0093] Here, Consumer 1 obtains the semantic loading tail pointer (tail=0) and head pointer (head=2), thus determining the amount of data to be consumed to be head-tail=2. Before loading, Consumer 1 has read the global producer sequence number (producer_seq=2) and the global consumer sequence number (consumer_seq=0), confirming the existence of new data; simultaneously, it reads the slot sequence number of index 0 and finds its value to be 0, equal to the current global consumer sequence number 0, indicating that the data is valid new data and has not been preemptively consumed by other consumers or overwritten by producers in a loop. After the above checks, Consumer 1 enters the tail pointer contention.
[0094] 2. Consumer 2 loads tail=0, head=2.
[0095] Here, consumer 2 also completes the same sequence number check process, obtains tail=0 and head=2, confirms that there is data to be consumed and that the data in slot 0 is valid, and prepares to compete for the tail pointer.
[0096] 3. Consumer 1 successfully completed CAS (0→1).
[0097] Here, Consumer 1 performs a CAS operation, updating the tail pointer from 0 to 1, successfully acquiring the read right for slot 0. Subsequently, Consumer 1 uses semantics to read data (data1) from this slot, and atomically increments the global consumer sequence number from 0 to 1 after reading, signifying completion of consumption. The incremented consumer sequence number marks that the data in this slot has been processed, preventing duplicate consumption or confusion with new data in the same slot in a new loop.
[0098] 4. Consumer serial numbers increment.
[0099] Here, the global consumer sequence number becomes 1, indicating that the data at index 0 has been successfully consumed and the progress has moved forward.
[0100] 5. Consumer 2's CAS (0→1) failed, retry.
[0101] Here, when Consumer 2 attempts to update tail from 0 to 1 using CAS, the CAS fails because tail has already been modified to 1 by Consumer 1. Consumer 2 detects the competition conflict and executes the retry process.
[0102] 6. Consumer 2 reloads tail=1.
[0103] Here, when retrying, consumer 2 retrieves the latest value of tail using atomic loading, obtaining tail=1. It then performs a sequence number check again: the global producer sequence number is still 2, while the consumer sequence number is 1; the two are not equal, indicating that there is still data to be consumed. It then reads the slot sequence number of index 1, which is 1, consistent with the current global consumer sequence number 1. The verification passes, and the data data2 is valid.
[0104] 7. Consumer 2 successfully completed CAS (1→2).
[0105] Here, consumer 2 executes CAS to update tail from 1 to 2, successfully acquires the read right of index 1 slot, reads data data2, and increments the global consumer sequence number.
[0106] 8. Consumer serial numbers increment.
[0107] Here, the global consumer sequence number changes from 1 to 2, indicating that all produced data has been consumed.
[0108] As shown above, by maintaining two independent global producer sequence numbers (producer_seq) and global consumer sequence numbers (consumer_seq) simultaneously in a circular buffer, the ABA problem is solved while avoiding the performance bottleneck of global sequence number contention. Furthermore, by grouping producers and consumers by NUMA nodes using the circular buffer, and through local priority commits and batch global synchronization, a single global contention is split into two phases, reducing the CAS conflict rate and improving throughput. Thus, on the one hand, the ABA problem is solved while avoiding the performance bottleneck of global sequence numbers, significantly reducing the CAS conflict rate compared to traditional single-sequence-number schemes; on the other hand, producers and consumers reduce cross-node access in the NUMA system, while effectively improving the system's concurrent throughput through local priority commits and batch global synchronization.
[0109] Figure 8 This is a schematic diagram of the structural composition of the lockless circular buffer concurrency control device provided in the embodiments of this application, which is applied to electronic devices, such as... Figure 8 As shown, the concurrent control device 800 of the lockless circular buffer includes: Producer module 801 is used to respond to write operations on the lockless circular buffer by multiple producers, update the write pointer from a first value to a second value through atomic operation competition, and increment the global producer sequence number.
[0110] Consumer module 802 is used to respond to multiple consumers' read operations on the lock-free circular buffer by reading the global producer sequence number and the global consumer sequence number; based on the global producer sequence number and the global consumer sequence number, it determines whether to perform a read operation on the lock-free circular buffer; when it is determined to perform an operation, it updates the read pointer from the third value to the fourth value through atomic operation competition, and increments the global consumer sequence number.
[0111] In some embodiments, the lockless circular buffer includes multiple data slots, each of which has a slot sequence number; the producer module 801 is further configured to reserve at least one data slot; write the data to be written to the reserved data slot; read the current global producer sequence number; and write the current global producer sequence number to the slot sequence number corresponding to the reserved data slot.
[0112] In some embodiments, the consumer module 802 is further configured to determine whether the global producer sequence number is equal to the global consumer sequence number. If they are equal, it is determined not to perform any operation; if they are not equal, it reads the slot sequence number of the target slot pointed to by the current read pointer; and determines whether the slot sequence number is equal to the global producer sequence number. If they are not equal, it is determined not to perform any operation; if they are equal, it is determined to perform any operation.
[0113] In some embodiments, the result of the atomic operation competition includes competition success and competition failure; when the atomic operation competition result is competition success, the producer module 801 is further configured to update the write pointer from a first value to a second value, and / or the consumer module 802 is further configured to update the read pointer from a third value to a fourth value; when the atomic operation competition result is competition failure, the producer module 801 and / or the consumer module 802 are further configured to retry the atomic operation with exponential backoff.
[0114] In some embodiments, the lock-free circular buffer includes a first read pointer and a first write pointer; the plurality of producers and the plurality of consumers are grouped according to non-consistent memory access NUMA nodes, and each NUMA node includes a second read pointer and a second write pointer.
[0115] In some embodiments, the producer module 801 is further configured to perform a local atomic operation on the second write pointer of the NUMA node to which it belongs; and / or, the consumer module 802 is further configured to perform a local atomic comparison-swap operation on the second read pointer of the NUMA node to which it belongs; the producer module 801 and / or the consumer module 802 are further configured to, according to a synchronization triggering condition, batch update the progress of the second write pointer and / or the second read pointer of the NUMA node to the first write pointer and / or the first read pointer through a global atomic comparison-swap operation.
[0116] In some embodiments, the synchronization triggering conditions include one or more of the following: the node local operation count reaches a first preset threshold, the NUMA node where the consumer is located is different from the NUMA node where the producer is located, the used space of the lockless circular buffer exceeds a preset proportion, and the number of retries reaches a second preset threshold.
[0117] In some embodiments, the producer module 801 and / or the consumer module 802 are further configured to migrate the producer and / or the consumer to a nearby NUMA node when the number of retries reaches a second preset threshold.
[0118] Those skilled in the art should understand that Figure 8 The implementation functions of each module in the concurrent control device of the lockless circular buffer shown can be understood by referring to the relevant description of the aforementioned method. Figure 8 The functions of each module in the concurrent control device of the lockless circular buffer shown can be implemented by a program running on the processor or by specific logic circuits.
[0119] Figure 9 This is a schematic structural diagram of an electronic device 900 provided in an embodiment of this application. The electronic device may be a server or a terminal. Figure 9 The illustrated electronic device 900 includes a processor 910, which can call and run computer programs from memory to implement the methods in the embodiments of this application.
[0120] Optionally, such as Figure 9 As shown, the electronic device 900 may further include a memory 920. The processor 910 can retrieve and run computer programs from the memory 920 to implement the methods described in the embodiments of this application.
[0121] The memory 920 can be a separate device independent of the processor 910, or it can be integrated into the processor 910.
[0122] Optionally, such as Figure 9As shown, the electronic device 900 may also include a transceiver 930, which the processor 910 can control to communicate with other devices. Specifically, it can send information or data to other devices or receive information or data sent by other devices.
[0123] The transceiver 930 may include a transmitter and a receiver. The transceiver 930 may further include antennas, and the number of antennas may be one or more.
[0124] It should be understood that the processor in the embodiments of this application may be an integrated circuit chip with signal processing capabilities. In implementation, the steps of the above method embodiments can be completed by integrated logic circuits in the processor's hardware or by instructions in software form. The processor described above can be a general-purpose processor, a digital signal processor (DSP), an application-specific integrated circuit (ASIC), a field-programmable gate array (FPGA), or other programmable logic devices, discrete gate or transistor logic devices, or discrete hardware components. It can implement or execute the methods, steps, and logic block diagrams disclosed in the embodiments of this application. The general-purpose processor can be a microprocessor or any conventional processor. The steps of the methods disclosed in the embodiments of this application can be directly embodied in the execution of a hardware decoding processor, or executed by a combination of hardware and software modules in the decoding processor. The software modules can be located in random access memory, flash memory, read-only memory, programmable read-only memory, electrically erasable programmable memory, registers, or other mature storage media in the art. The storage medium is located in memory, and the processor reads information from the memory and, in conjunction with its hardware, completes the steps of the above method.
[0125] It is understood that the memory in the embodiments of this application can be volatile memory or non-volatile memory, or may include both volatile and non-volatile memory. The non-volatile memory can be read-only memory (ROM), programmable read-only memory (PROM), erasable programmable read-only memory (EPROM), electrically erasable programmable read-only memory (EEPROM), or flash memory. The volatile memory can be random access memory (RAM), which is used as an external cache. By way of example, but not limitation, many forms of RAM are available, such as Static Random Access Memory (SRAM), Dynamic Random Access Memory (DRAM), Synchronous DRAM (SDRAM), Double Data Rate SDRAM (DDR SDRAM), Enhanced Synchronous DRAM (ESDRAM), Synchlink DRAM (SLDRAM), and Direct Rambus RAM (DR RAM). It should be noted that the memory used in the systems and methods described herein is intended to include, but is not limited to, these and any other suitable types of memory.
[0126] It should be understood that the above-described memory is exemplary and not a limiting description. For example, the memory in the embodiments of this application may also be static random access memory (SRAM), dynamic random access memory (DRAM), synchronous dynamic random access memory (SDRAM), double data rate synchronous dynamic random access memory (DDR SDRAM), enhanced synchronous dynamic random access memory (ESDRAM), synchronous link dynamic random access memory (SLDRAM), and direct memory bus RAM (DR RAM), etc. That is to say, the memory in the embodiments of this application is intended to include, but is not limited to, these and any other suitable types of memory.
[0127] This application also provides a computer-readable storage medium for storing computer programs.
[0128] Optionally, the computer-readable storage medium can be applied to the server in the embodiments of this application, and the computer program causes the computer to execute the corresponding processes implemented by the server in the various methods of the embodiments of this application. For the sake of brevity, it will not be described in detail here.
[0129] This application also provides a computer program product, including computer program instructions.
[0130] Optionally, the computer program product can be applied to the server in the embodiments of this application, and the computer program instructions cause the computer to execute the corresponding processes implemented by the server in the various methods of the embodiments of this application. For the sake of brevity, they will not be described in detail here.
[0131] This application also provides a computer program.
[0132] Optionally, the computer program can be applied to the server in the embodiments of this application. When the computer program is run on the computer, it causes the computer to execute the corresponding processes implemented by the server in the various methods of the embodiments of this application. For the sake of brevity, it will not be described in detail here.
[0133] Those skilled in the art will recognize that the units and algorithm steps of the various examples described in conjunction with the embodiments disclosed herein can be implemented in electronic hardware, or a combination of computer software and electronic hardware. Whether these functions are implemented in hardware or software depends on the specific application and design constraints of the technical solution. Those skilled in the art can use different methods to implement the described functions for each specific application, but such implementation should not be considered beyond the scope of this application.
[0134] Those skilled in the art will understand that, for the sake of convenience and brevity, the specific working processes of the systems, devices, and units described above can be referred to the corresponding processes in the foregoing method embodiments, and will not be repeated here.
[0135] In the several embodiments provided in this application, it should be understood that the disclosed systems, apparatuses, and methods can be implemented in other ways. For example, the apparatus embodiments described above are merely illustrative; for instance, the division of units is only a logical functional division, and in actual implementation, there may be other division methods. For example, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Furthermore, the coupling or direct coupling or communication connection shown or discussed may be through some interfaces; the indirect coupling or communication connection between apparatuses or units may be electrical, mechanical, or other forms.
[0136] The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the units can be selected to achieve the purpose of this embodiment according to actual needs.
[0137] In addition, the functional units in the various embodiments of this application can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit.
[0138] If the aforementioned functions are implemented as software functional units and sold or used as independent products, they can be stored in a computer-readable storage medium. Based on this understanding, the technical solution of this application, in essence, or the part that contributes to the prior art, or a portion of the technical solution, can be embodied in the form of a software product. This computer software product is stored in a storage medium and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute all or part of the steps of the methods described in the various embodiments of this application. The aforementioned storage medium includes various media capable of storing program code, such as USB flash drives, portable hard drives, read-only memory (ROM), random access memory (RAM), magnetic disks, or optical disks.
[0139] The above description is merely a specific embodiment of this application, but the scope of protection of this application is not limited thereto. Any changes or substitutions that can be easily conceived by those skilled in the art within the scope of the technology disclosed in this application should be included within the scope of protection of this application.
Claims
1. A concurrent control method for a lock-free circular buffer, characterized in that, The method includes: In response to multiple write operations to the lockless circular buffer, the write pointer is updated from a first value to a second value through atomic operation competition, and the global producer sequence number is incremented; In response to multiple consumers' read operations on the lock-free circular buffer, the global producer sequence number and the global consumer sequence number are read. Based on the global producer sequence number and the global consumer sequence number, it is determined whether to perform a read operation on the lock-free circular buffer. When it is determined to perform the operation, the read pointer is updated from the third value to the fourth value through atomic operation competition, and the global consumer sequence number is incremented.
2. The method according to claim 1, characterized in that, The lockless circular buffer includes multiple data slots, each of which has a slot sequence number; After updating the write pointer from the first value to the second value, the method further includes: Reserve at least one data slot; Write the data to be written to the reserved data slot; Read the current global producer sequence number; Write the current global producer sequence number into the slot sequence number corresponding to the reserved data slot.
3. The method according to claim 1, characterized in that, The step of determining whether to perform a read operation on the lock-free circular buffer based on the global producer sequence number and the global consumer sequence number includes: Determine whether the global producer sequence number and the global consumer sequence number are equal. If they are equal, determine that no operation will be performed; if they are not equal, read the slot sequence number of the target slot pointed to by the current read pointer. Determine whether the slot sequence number is equal to the global producer sequence number. If they are not equal, determine that no operation will be performed; if they are equal, determine that an operation will be performed.
4. The method according to claim 1, characterized in that, The outcome of the atomic operation competition includes successful competition and failed competition; When the result of the atomic operation competition is a successful competition, the write pointer is updated from the first value to the second value, and / or the read pointer is updated from the third value to the fourth value; When the competition for the atomic operation fails, the atomic operation is retried after exponential backoff.
5. The method according to claim 4, characterized in that, The lock-free circular buffer includes a first read pointer and a first write pointer; the multiple producers and the multiple consumers are grouped according to non-consistent memory access NUMA nodes, and each NUMA node includes a second read pointer and a second write pointer; The step of updating the write pointer from a first value to a second value, and / or updating the read pointer from a third value to a fourth value, includes: Each producer performs a local atomic operation on the second write pointer of its NUMA node; and / or each consumer performs a local atomic compare-swap operation on the second read pointer of its NUMA node; Based on the synchronization triggering condition, the progress of the second write pointer and / or the second read pointer of the NUMA node is updated in batches to the first write pointer and / or the first read pointer through a global atomic comparison and exchange operation.
6. The method according to claim 5, characterized in that, The synchronization triggering conditions include one or more of the following: The node local operation count reaches the first preset threshold, the consumer's NUMA node is detected to be different from the producer's NUMA node, the used space of the lockless ring buffer exceeds the preset ratio, and the number of retries reaches the second preset threshold.
7. The method according to claim 6, characterized in that, When the number of retries reaches a second preset threshold, the producer and / or the consumer will be migrated to a nearby NUMA node.
8. An electronic device, characterized in that, include: A processor and a memory for storing a computer program, the processor for calling and running the computer program stored in the memory to perform the method as described in any one of claims 1 to 7.
9. A computer-readable storage medium, characterized in that, Used to store a computer program that causes a computer to perform the method as described in any one of claims 1 to 7.
10. A computer program product, characterized in that, It includes computer program instructions that cause a computer to perform the method as described in any one of claims 1 to 7.