A processing method and apparatus of a thread
By putting high-priority threads into a sleep state and having them act as proxies for low-priority threads, the priority inversion problem in read-write lock scenarios is solved, thus improving thread execution efficiency.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- HONOR DEVICE CO LTD
- Filing Date
- 2024-07-31
- Publication Date
- 2026-06-12
AI Technical Summary
In read-write lock scenarios, the priority inversion problem caused by low-priority threads preempting CPU resources by high-priority threads leads to reduced execution efficiency.
By putting high-priority threads into a sleep state and acting as proxies for low-priority threads, we can prevent low-priority threads from preempting CPU resources, ensure that high-priority threads execute smoothly and release read locks as soon as possible, thereby efficiently acquiring write locks.
This reduces the time high-priority threads wait for write locks, improves thread execution efficiency, and avoids performance degradation caused by priority inversion.
Smart Images

Figure CN120762825B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of computer technology, and in particular to a method and apparatus for processing threads. Background Technology
[0002] Read-write locks are a synchronization mechanism in concurrent programming. A read-write lock has two states: a read lock state and a write lock state. When the read-write lock is in the read lock state, the thread holding the lock (called the read lock thread, or "reader") can perform read operations on the shared resource; when the read-write lock is in the write lock state, the thread holding the lock (called the write lock thread, or "writer") can perform write operations on the shared resource.
[0003] A read-write lock allows multiple read-lock threads to perform read operations on a shared resource simultaneously (within a certain period). However, only one write-lock thread can perform a write operation on the shared resource within a given period. That is, within the same timeframe, multiple read-lock threads or one write-lock thread can access the shared resource. When multiple read-lock threads are performing read operations on the shared resource, threads requesting to write to the shared resource must wait for all read-lock threads to release their locks. In this situation, a priority inversion problem may occur.
[0004] For example, suppose the thread requesting a write operation on a shared resource is a high-priority thread, and one of the multiple read lock threads is a low-priority thread. While the low-priority thread is performing a read operation on the shared resource, other threads (e.g., medium-priority threads) may preempt the CPU resources of that low-priority thread. In this case, the medium-priority thread executes before the high-priority thread, causing the high-priority thread to wait longer and reducing its execution efficiency. Summary of the Invention
[0005] This application provides a thread processing method and apparatus that can solve the priority inversion problem in read-write lock scenarios and improve thread execution efficiency.
[0006] To achieve the above objectives, the embodiments of this application adopt the following technical solutions:
[0007] Firstly, a thread processing method is provided, applied to an electronic device. The electronic device includes a target processor, the target processor includes a target run queue, and the target run queue includes a first thread, a second thread, and a third thread. The method includes: when the first thread holds a read lock on a target resource, the second thread enters a sleep state and is not removed from the target run queue; when the first thread releases the read lock on the target resource, the second thread is awakened and holds a write lock on the target resource; after the second thread finishes running, the third thread runs, and the priority of the third thread is lower than the priority of the second thread but higher than the priority of the first thread.
[0008] Based on the method provided in this application, when the first thread holds a read lock on the target resource, the second thread can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first thread. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources. This prevents the third thread from preempting the first thread's CPU resources, allowing the first thread to execute smoothly and release the read lock as soon as possible. Consequently, the second thread can acquire a write lock as quickly as possible, reducing the time the second thread waits for the write lock and improving its execution efficiency.
[0009] In one possible implementation, before the second thread enters a sleep state and is not removed from the target run queue, the method further includes: the second thread reading a first parameter or a second parameter. The first parameter indicates at least one thread holding a read lock on the target resource, these at least one threads being arranged sequentially based on the time order in which they held the read locks on the target resource, and including the first thread. The second parameter indicates a first target thread, which is the thread among the at least one threads that held the read lock on the target resource the latest. That is, after the second thread learns of the thread holding the read lock on the target resource, it can enter a sleep state without being removed from the target run queue. After the second thread enters a sleep state, the target processor can run the first thread. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources, thus preventing the third thread from preempting the first thread's CPU resources. This allows the first thread to execute smoothly and release the read lock as soon as possible. Consequently, the second thread can acquire a write lock as quickly as possible, reducing the time the second thread waits for the write lock and improving its execution efficiency.
[0010] In one possible implementation, the method further includes: a second thread writing information corresponding to the first target thread into a third parameter; the second thread notifying the target processor to run the first target thread based on the third parameter; and the first target thread running on the target processor. It should be noted that since the second thread is not removed from the target run queue, and the second thread is the highest priority thread in the target run queue, the second thread can be selected by the target processor (or scheduler) as the next thread to run (soon to run). Furthermore, since the second thread enters a sleep state and does not actually run, the second thread can notify the target processor to run the first target thread (e.g., the first thread), and the second thread can act as a proxy for the first target thread (e.g., the first thread), with the target processor actually running the first target thread (e.g., the first thread). That is, the first target thread (e.g., the first thread) can run on the target processor "as" the second thread. Therefore, when the first thread is running, if there is a thread with a higher priority than the first thread but lower priority than the second thread (e.g., a third thread), the third thread will not preempt the CPU resources of the first thread. This is because the third thread believes that the CPU is "actually running" the second thread. Since the second thread has a higher priority than the third thread, the third thread will not preempt CPU resources. This ensures that the first thread runs smoothly and releases the read lock as soon as possible, allowing the second thread to acquire the write lock quickly. This reduces the time the second thread spends waiting for the write lock and improves its execution efficiency.
[0011] In one possible implementation, before the second thread reads the first or second parameter, the method further includes: the first thread writing first information into the first and second parameters, the first information including the thread identifier of the first thread. Thus, after the second thread reads the first or second parameter, it can know that the thread holding the read lock on the target resource includes the first thread. With the first thread holding the read lock on the target resource, the second thread can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first thread. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources, thus preventing the third thread from preempting the first thread's CPU resources. This allows the first thread to execute smoothly and release the read lock as soon as possible. Consequently, the second thread can acquire the write lock as quickly as possible, reducing the time the second thread waits for the write lock and improving its execution efficiency.
[0012] In one possible implementation, after the first thread releases the read lock on the target resource, the method further includes: the first thread updating a first parameter, and deleting the first information in the updated first parameter; the first thread determining whether the updated first parameter is null; and if the updated first parameter is null, the first thread waking up the second thread. It should be noted that a null updated first parameter indicates that there are currently no threads holding the read-write lock on the target resource (including read lock threads and write lock threads). In this case, the second thread can be woken up so that it can hold the write lock and perform write operations on the target resource.
[0013] In one possible implementation, the method further includes: if the first parameter updated by the first thread is null, the first thread clears the second parameter. This avoids other threads misjudging the thread holding the read-write lock of the target resource, thus preventing impact on the running efficiency of other threads. It is understandable that different threads can hold the same read-write lock at different times. For example, in the first time period, thread A could be the thread that held the read lock of the target resource the latest, and the second parameter includes thread A's information. In the second time period, thread D could be the thread that held the read lock of the target resource the latest. If the second parameter still includes thread A's information, it could cause misjudgment among threads in the read-write lock waiting queue, mistakenly identifying thread A as the current holder of the read-write lock, when in fact, thread D is the holder of the read-write lock in the second time period. Therefore, thread A can clear the second parameter, allowing thread D to write its own information into the second parameter, preventing misjudgment among the next batch of threads waiting for the read-write lock (i.e., threads waiting for the read-write lock in the second time period).
[0014] In one possible implementation, the method further includes: if the first parameter updated by the first thread is not null and the first thread is the first target thread, the first thread updates the second parameter. The updated second parameter is used to indicate the thread that held the read lock on the target resource the latest among the updated first parameters. After updating the second parameter, the first thread can notify the thread in the waiting queue corresponding to the read lock (e.g., the second thread) of the updated second parameter, so that the thread in the waiting queue (e.g., the second thread) updates its own recorded third parameter. Notifying the thread in the waiting queue (e.g., the second thread) of the updated second parameter incurs overhead. To minimize overhead, the second parameter can be updated only if the first parameter updated by the first thread is not null and the first thread is the first target thread. This avoids frequent updates to the second parameter, preventing unnecessary notification of the updated second parameter to the thread in the waiting queue (e.g., the second thread) (or, avoiding frequent wake-ups of the thread in the waiting queue), thus saving overhead.
[0015] In one possible implementation, the method further includes: if the first parameter updated by the first thread is not null and the first thread is the first target thread, the first thread wakes up the second thread; the second thread reads the first parameter updated by the first thread or the second parameter updated by the first thread, and updates the first target thread in the third parameter to the second target thread, where the second target thread is the thread that held the read lock on the target resource the latest in the first parameter updated by the first thread. The second thread notifies the target processor to run the second target thread based on the updated third parameter; the second target thread runs on the target processor. In this way, the second thread can act as a proxy for the second target thread (e.g., the fourth thread), and the target processor actually runs the second target thread (e.g., the fourth thread). That is, the second target thread (e.g., the fourth thread) can run on the target processor "as" the second thread. Therefore, when the fourth thread runs, if there is a thread with a priority higher than the fourth thread but lower than the second thread (e.g., the third thread), the third thread will not preempt the CPU resources of the fourth thread. This is because the third thread believes that the CPU is "actually running" the second thread, and since the priority of the second thread is higher than the priority of the third thread, the third thread will not preempt the CPU resources. This ensures that the fourth thread runs smoothly and releases the read lock as soon as possible, allowing the second thread to acquire the write lock quickly. This reduces the time the second thread spends waiting for the write lock and improves its execution efficiency.
[0016] In one possible implementation, after the second thread reads the first or second parameter, the method further includes: the second thread adding itself to a waiting queue; and the first thread waking up the second thread including: the first thread waking up the second thread based on the waiting queue. In this way, the first thread can accurately wake up the thread that needs to be woken up (e.g., the second thread) based on the waiting queue.
[0017] In one possible implementation, the target run queue also includes a fourth thread holding a read lock on the target resource. The second thread is awakened when the first thread releases its read lock, specifically when both the first and fourth threads release their read locks. Thus, when multiple threads (e.g., the first and fourth threads) hold read locks on the target resource, the second thread needs to wait for a write lock and can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first and fourth threads. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) will not preempt CPU resources. This prevents the third thread from preempting the CPU resources of the first and fourth threads, allowing them to execute smoothly and release read locks as quickly as possible. Consequently, the second thread, upon being awakened, can quickly acquire a write lock, reducing its waiting time and improving its execution efficiency.
[0018] In one possible implementation, the method further includes: a fourth thread writing second information into the first and second parameters, the second information including the thread identifier of the fourth thread. Thus, after reading the first or second parameter, the second thread can determine that the thread holding the read lock on the target resource includes the fourth thread. With the fourth thread holding the read lock on the target resource, the second thread can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first thread. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources, thus preventing the third thread from preempting the fourth thread's CPU resources. This allows the fourth thread to execute smoothly and release the read lock as quickly as possible. Consequently, the second thread can acquire the write lock as quickly as possible, reducing the time the second thread waits for the write lock and improving its execution efficiency.
[0019] In one possible implementation, after the fourth thread releases the read lock on the target resource, the method further includes: the fourth thread updating the first parameter, and deleting the second information from the updated first parameter; the fourth thread determining whether the updated first parameter is null; and if the updated first parameter is null, the fourth thread waking up the second thread. It should be noted that a null updated first parameter indicates that there are currently no threads holding the read-write lock on the target resource (including read lock threads and write lock threads). In this case, the second thread can be woken up so that it can hold the write lock and perform write operations on the target resource.
[0020] Secondly, this application provides a chip system including one or more interface circuits and one or more processors. The interface circuits and processors are interconnected via lines. The aforementioned chip system can be applied to electronic devices including communication modules and memory. The interface circuits are used to receive signals from the memory of the electronic device and send the received signals to the processor, the signals including computer instructions stored in the memory. When the processor executes the computer instructions, the electronic device can perform the methods described in the first aspect and any of its possible design embodiments.
[0021] Thirdly, this application provides a computer-readable storage medium including computer instructions. When the computer instructions are executed on an electronic device (such as a mobile phone), they cause the electronic device to perform the methods described in the first aspect and any of its possible design embodiments.
[0022] Fourthly, this application provides a computer program product that, when run on a computer, causes the computer to perform the method described in the first aspect and any possible design thereof.
[0023] Fifthly, embodiments of this application provide a thread processing apparatus, including a processor and a memory coupled together. The memory stores program instructions, which, when executed by the processor, cause the apparatus to implement the method described in the first aspect and any possible design of the above. The apparatus may be an electronic device or a server device; or it may be a component of an electronic device or a server device, such as a chip.
[0024] Sixthly, embodiments of this application provide a thread processing apparatus, which can be divided into different logical units or modules according to function, each unit or module performing different functions, so that the apparatus performs the method described in the first aspect and any possible design method described above.
[0025] It is understood that the beneficial effects achieved by the chip system described in the second aspect, the computer-readable storage medium described in the third aspect, the computer program product described in the fourth aspect, and the apparatus described in the fifth and sixth aspects can be referred to the beneficial effects in the first aspect and any of its possible design embodiments, which will not be repeated here. Attached Figure Description
[0026] Figure 1 This is a schematic diagram of the execution timing of a multithreaded system based on a mutex lock.
[0027] Figure 2 This is a schematic diagram of the execution timing of a multithreaded system based on a read-write lock.
[0028] Figure 3 This is a schematic diagram of a multi-threaded scheduling scheme based on a mutex lock in related technologies.
[0029] Figure 4 A schematic diagram of a multi-threaded scheduling scheme based on a mutex lock provided in an embodiment of this application;
[0030] Figure 5 A flowchart illustrating a thread processing method provided in an embodiment of this application;
[0031] Figure 6A A flowchart illustrating yet another thread processing method provided in an embodiment of this application;
[0032] Figure 6B A flowchart illustrating yet another thread processing method provided in an embodiment of this application;
[0033] Figure 7 A flowchart illustrating yet another thread processing method provided in an embodiment of this application;
[0034] Figure 8 A flowchart illustrating yet another thread processing method provided in an embodiment of this application;
[0035] Figure 9 This is a schematic diagram of the structure of an electronic device provided in an embodiment of this application;
[0036] Figure 10 This is a schematic diagram of a chip system provided in an embodiment of this application. Detailed Implementation
[0037] To ensure clarity and conciseness in the description of the following embodiments, a brief introduction to the relevant concepts or technologies is given first:
[0038] Concurrent programming: running multiple threads "simultaneously" on a single processor, each thread can perform a corresponding task.
[0039] Threads need resource scheduling to execute tasks, that is, to acquire the right to use the central processing unit (CPU). In multi-threaded scenarios, CPU resource scheduling for each thread can be based on time-sharing scheduling mechanisms. For example, all threads can take turns using the CPU, distributing the CPU time (CPU resource) to each thread evenly. The time period each thread occupies the CPU can be called a time slice. Alternatively, CPU resource allocation can be based on the priority of each thread. For example, threads with higher priority can be given priority to use the CPU; if threads have the same priority, a thread will be randomly selected to use the CPU first and acquire the CPU time (CPU resource) first. Concurrent programming can improve program execution efficiency and increase CPU utilization.
[0040] The execution states of a thread include: new, runnable / waiting to be executed, running, blocked, and dead.
[0041] The "new" state refers to the state where a thread is created using the `new` operator (e.g., `new Thread(r)`) but has not yet started running. Threads in the "new" state are not yet running.
[0042] After creating a new thread, you can call the thread's start() method to execute it. Once the start() method returns, the thread is in a ready state, waiting for the processor to schedule it.
[0043] Once a thread acquires CPU time (obtains CPU resources), it enters the running state and executes the contents of the run() method.
[0044] Threads may enter a blocked state for various reasons during execution: For example, a thread may call `sleep()` to enter a sleep state. Sleep states can be interruptible or uninterruptible. Alternatively, a thread may call an operation that is blocked on input / output (I / O) and remain in an uninterrupted state until the I / O operation completes. Or, a thread may be blocked while waiting for a lock (mutex, read-write lock, etc.) to be released. Or, a thread may be blocked while waiting for other triggering conditions, such as waiting for a condition variable. A blocked state means that the running thread has not finished executing but has temporarily relinquished CPU resources, waiting for the next opportunity to acquire them.
[0045] There are several reasons why a thread might die: for example, the run() method might terminate normally; or an uncaught exception might terminate the run() method, causing the thread to die abruptly.
[0046] A mutex (mutual exclusion lock) is a synchronization mechanism in concurrent programming used to protect shared resources from exclusive access in a multi-threaded environment. A mutex ensures that only one thread can operate on / access a shared resource (e.g., a critical section) at any given time, while other threads must wait. The thread capable of operating on the shared resource (e.g., thread A) can be considered the thread holding the lock (i.e., the mutex), meaning thread A is the lock owner. Meanwhile, other threads cannot operate on the critical section; these threads are called lock waiters. A waiter can only access the critical section after the owner has finished operating on it and released the lock.
[0047] Due to the mutual exclusion characteristic of mutex locks (that is, when multiple threads access the same critical section, only the lock owner can access the critical section), priority inversion may occur during thread execution.
[0048] For example, such as Figure 1 As shown, suppose a low-priority thread (e.g., thread C) in the running state acquires the lock first and can operate on the critical section. When a high-priority thread (e.g., thread A) wants to operate on the critical section, thread A needs to wait because the mutex lock is already held by thread C. However, while thread C is running, a medium-priority thread (e.g., thread B) may preempt the CPU resources of the low-priority thread (e.g., thread C). At this time, thread C needs to wait for thread B to release the CPU resources before it can continue running. After thread C finishes running, it releases the lock, and then thread A can acquire the lock and operate on the critical section. Because thread B preempted thread C's CPU resources, thread C waits, which in turn causes thread A to wait. Here, thread A's priority is higher than thread B's priority, but thread A's execution order is after thread B, which is a priority inversion problem.
[0049] Similarly, read-write locks can also suffer from priority inversion, which occurs when a high-priority thread waits for a low-priority thread to finish its work, but the low-priority thread's CPU resources are preempted, leading to priority inversion.
[0050] For example, Figure 2A schematic diagram of multithreaded execution based on read-write locks is provided. Assume thread C is the first thread to acquire the read lock, and thread A wants to acquire the write lock. Thread A needs to wait for thread C to release the read lock. Thread A can have a high priority, and thread C can have a low priority. While thread A waits for thread C to release the read lock, thread C can acquire CPU resources and execute its corresponding task. Ideally, thread C can successfully complete its task, release the read lock, and wake up thread A, allowing thread A to acquire the write lock. However, in reality, because thread C has a low priority, during thread C's task execution, it may be preempted by a medium-priority thread B. Thread B, having preempted the CPU resources, executes its task first, causing thread C to be unable to execute its task. Thread C needs to wait for thread B to complete its task and release the CPU resources before it can regain CPU resources to execute its task. After completing its task, thread B can release the read lock and send a wake-up broadcast. Thread A receives the wake-up broadcast and continues executing its task.
[0051] In the process of thread A waiting for thread C to release the read lock, thread C is blocked because the CPU resources are preempted by the medium-priority thread B. This causes the medium-priority thread B to execute before the high-priority thread A, which is a priority inversion problem. As a result, the high-priority thread waits for a longer time, which reduces the execution efficiency of the high-priority thread.
[0052] Among related technologies, solutions to the aforementioned high-priority inversion problem include priority inheritance and priority ceiling.
[0053] One approach, the priority ceiling, raises a thread's priority to the highest among all threads that can access that resource when the thread accesses it. This highest priority can be called the priority ceiling for that resource. However, this approach raises the priority of any thread accessing the shared resource, potentially causing lower-priority threads to block higher-priority threads.
[0054] The priority inheritance scheme works like this: when a low-priority thread holding a shared resource blocks a high-priority thread, the thread's priority is dynamically changed. For example, when a thread (e.g., thread A) requests / accesses a shared resource (e.g., S), if S is being used by thread C, thread A can compare thread C's priority with its own. If thread C's priority is lower than its own (i.e., thread A's) priority, then thread C's priority is raised to its own. After thread C releases resource S, thread C's original priority is restored.
[0055] The aforementioned priority inheritance scheme and priority ceiling scheme both require dynamically changing the thread priority. This application provides a thread processing method that does not require changing the thread priority, thus solving the mutex priority inversion problem and the read-write lock priority inversion problem. It can reduce the time that threads (e.g., high-priority threads) wait for read-write locks, thereby improving thread execution efficiency.
[0056] The technical solutions in the embodiments of this application will be described below. In the description of the embodiments of this application, the terminology used in the following embodiments is for the purpose of describing specific embodiments only and is not intended to be a limitation of this application. As used in the specification and appended claims of this application, the singular expressions “a,” “the,” “the,” “the,” and “this” are intended to also include expressions such as “one or more,” unless the context clearly indicates otherwise. It should also be understood that in the following embodiments of this application, “at least one” and “one or more” refer to one or more (including two). The term “and / or” is used to describe the relationship between related objects, indicating that three relationships can exist; for example, A and / or B can represent: A alone, A and B simultaneously, or B alone, where A and B can be singular or plural. The character “ / ” generally indicates that the preceding and following related objects are in an “or” relationship.
[0057] References to "one embodiment" or "some embodiments" in this specification mean that one or more embodiments of this application include a specific feature, structure, or characteristic described in connection with that embodiment. Therefore, the phrases "in one embodiment," "in some embodiments," "in other embodiments," "in still other embodiments," etc., appearing in different parts of this specification do not necessarily refer to the same embodiment, but rather mean "one or more, but not all, embodiments," unless otherwise specifically emphasized. The terms "comprising," "including," "having," and variations thereof mean "including but not limited to," unless otherwise specifically emphasized. The term "connection" includes direct connections and indirect connections, unless otherwise stated. "First" and "second" are used for descriptive purposes only and should not be construed as indicating or implying relative importance or implicitly specifying the number of technical features indicated.
[0058] In the embodiments of this application, the terms "exemplary" or "for example" are used to indicate that something is an example, illustration, or description. Any embodiment or design that is described as "exemplary" or "for example" in the embodiments of this application should not be construed as being more preferred or advantageous than other embodiments or design. Specifically, the use of the terms "exemplary" or "for example" is intended to present the relevant concepts in a specific manner.
[0059] For ease of understanding, the thread processing method provided in the embodiments of this application will be described in detail below with reference to the accompanying drawings.
[0060] For example, such as Figure 3 As shown, assume the current run queue (rq) includes high-priority threads (e.g., thread X), medium-priority threads (e.g., thread Y), and low-priority threads (e.g., thread A). In the original Linux kernel scheduling scheme, when a high-priority thread (e.g., thread X) wants to operate on a target resource (e.g., a critical section), if it finds that the mutex lock is already held by a low-priority thread (e.g., thread A), thread X can be removed from the run queue (i.e., cleared from the run queue). At this time, the remaining threads in the run queue include thread Y and thread A. When the CPU performs scheduling, since thread Y has a higher priority than thread A, the CPU will choose thread Y to run, while thread A will be delayed, thus extending the waiting time of thread X.
[0061] Let's continue with the example where the current run queue includes high-priority threads (e.g., thread X), medium-priority threads (e.g., thread Y), and low-priority threads (e.g., thread A). Figure 4 As shown in the thread processing method provided in this application embodiment, when a high-priority thread (e.g., thread X) wants to operate on a critical section, even if it finds that the mutex lock is already held by a low-priority thread (e.g., thread A), thread X will not be removed from the run queue (i.e., cleared from the run queue). Thus, when the CPU schedules, it will select the highest-priority thread X to run. However, thread X needs to wait for thread A to release the mutex lock, so it is only "ostensibly" running on the CPU. At this time, the CPU can actually run the low-priority thread A. That is, thread X can act as a "proxy" for thread A. During the execution of thread A, the thread that thread Y "sees" running is thread X, which is "ostensibly" running on the CPU, not thread A, which is actually running on the CPU. Since the priority of thread X is higher than that of thread Y, thread Y will not preempt the CPU resources of the actually running thread A, thereby ensuring the smooth operation of thread A and reducing the lock waiting time of thread X.
[0062] The above describes methods applicable to resolving the priority inversion problem in mutex locks. However, these methods cannot be directly applied to read-write locks to address the priority inversion issue. This is because when a read-write lock is in a read-lock state (e.g., one thread holds the read lock), other threads wanting to hold the read lock can also acquire it; that is, multiple threads hold the read-write lock at this time. Each time a new thread acquires the read lock, the parameters corresponding to the holding thread (e.g., owner) are updated. In other words, the thread recorded in the owner only represents that the thread once held the read lock (a read-lock state read-write lock), and does not represent that the thread actually holds the read lock (the thread may have already released the read lock).
[0063] Since a thread (e.g., a high-priority thread, such as thread X) does not know which thread actually holds the read lock, thread X will remove it from the run queue. If the actual holder of the read lock is a low-priority thread (e.g., thread A), since thread X has already been removed from the run queue, thread X cannot delegate the execution of thread A, which could lead to thread A potentially having its CPU resources preempted by other threads (e.g., a medium-priority thread Y).
[0064] This application provides a thread processing method that can solve the priority inversion problem of read-write locks.
[0065] The method provided in this application is applicable to various types of read-write locks. For example, these various types of read-write locks may include read-write locks in the Linux kernel, read-write locks within the ART virtual machine in the Android system, and read-write locks implemented using other methods. The underlying implementation of these read-write locks may be based on the Linux kernel's futex lock.
[0066] like Figure 5 As shown in the figure, this application provides a thread processing method applied to an electronic device. The electronic device includes a target processor, the target processor includes a target run queue, and the target run queue includes a first thread, a second thread, and a third thread. The method includes:
[0067] 501. The first thread holds a read lock on the target resource.
[0068] In this embodiment, a thread holding a read lock can be considered to be a thread holding a read-write lock that is in a read-lock state. A first thread holding a read lock on a target resource means that the first thread holds a read-write lock on the target resource, and this read-write lock is in a read-lock state. That is, the first thread is a read-lock thread. The first thread can perform read operations on the target resource.
[0069] The target resource can refer to a pre-defined shared resource, such as a variable or a critical section.
[0070] It is understood that a read-write lock for a target resource can correspond to one or more parameters (also referred to as members or member variables). For example, the parameters of a read-write lock may include the read-write lock's status flag bits and the read-write lock's waiting queue.
[0071] The status flags of a read-write lock indicate the number and type of threads holding the lock (read-lock thread or write-lock thread). The status flags can be represented by the flag symbol. For example, when the status flag is -1 (flag = -1), it means there is one thread holding the lock, and that thread is a write-lock thread. When the status flag is 0 (flag = 0 or flag == 0), it means there are zero threads holding the lock; no thread holds the lock. When the status flag is 1 (flag = 1), it means there is one thread holding the lock, and that thread is a read-lock thread. When the status flag is 2 (flag = 2), it means there are two threads holding the lock, and both threads are read-lock threads. In other words, when the number of threads holding a read-write lock is greater than 1, there are multiple threads holding the read-write lock, and all of these multiple threads are read lock threads. The maximum possible number of read lock threads can be the logical number of CPUs.
[0072] Before the first thread acquires a read lock on the target resource, it can query the read-write lock's flag (e.g., flag). If the flag meets the first condition, the first thread can acquire the read lock.
[0073] For example, the first condition could be that the read-write lock's flag bit is greater than or equal to 0 and less than a preset value. The preset value refers to the maximum number of threads that can simultaneously read the lock. Assuming the preset value is 'a' (where 'a' is an integer greater than 1, e.g., 'a = 8'), that is, when the read-write lock's flag bit is greater than or equal to 0 and less than 'a' (e.g., when the read-write lock's flag bit is 0), the first condition is considered met, and the first thread can hold the read lock (i.e., can perform read operations on the target resource).
[0074] In some embodiments, when the read-write lock is in a read lock state, the read-write lock's waiting queue may include threads waiting for a write lock. These threads can hold the write lock (i.e., hold the read-write lock, and the read-write lock is in a write lock state) after all read lock threads of the target resource release their read locks (i.e., release the read-write lock in a read lock state). The read-write lock's waiting queue can be represented by `waiter_list`.
[0075] In some embodiments, the parameters corresponding to the read-write lock of the target resource may further include a first parameter. The first parameter can be used to indicate at least one thread holding the read lock of the target resource (i.e., holding the read-write lock of the target resource, and the read-write lock is in a read lock state), and the at least one thread is arranged sequentially based on the time order in which the read lock is held. The first parameter can also be called the read-write lock holding thread queue (or read lock thread queue), and can be represented by owner_list.
[0076] In some embodiments, the parameters corresponding to the read-write lock of the target resource may further include a second parameter. The second parameter is used to indicate the thread in the owner_list that held the read lock the latest (i.e., the thread that requested the read operation on the target resource the latest). The second parameter can be represented by owner.
[0077] In some embodiments, when the first thread holds a read lock on the target resource, it can write first information into the first parameter, the first information including the thread identifier of the first thread.
[0078] The first thread writes the first information into the first parameter in a "new" manner, meaning that the information that originally existed in the first parameter remains unchanged. After the first thread writes the first information into the first parameter, the information in the first parameter includes the original information and the first information, that is, the first information is newly added.
[0079] In some embodiments, the first thread can write the first information into the second parameter.
[0080] The first thread writes the first information into the second parameter in the form of "replacement". That is, when the first thread writes the first information into the second parameter, the information that originally existed in the second parameter is replaced with the first information.
[0081] Understandably, since the information in the second parameter can be continuously replaced by later read lock threads, the information in the second parameter can indicate the thread that holds the read lock on the target resource the latest (i.e., the latest arriving read lock thread).
[0082] Additionally, when the first thread holds a read lock on the target resource, it can update the read-write lock's status flag. For example, before the first thread holds the read lock on the target resource, the read-write lock's status flag can be 0; after the first thread holds the read lock on the target resource, it can update the read-write lock's status flag to 1.
[0083] 502. If the first thread holds a read lock on the target resource, the second thread enters a sleep state and is not removed from the target run queue.
[0084] The second thread is the thread waiting for the write lock. The second thread can query the read-write lock status of the target resource. If the read-write lock of the target resource is in read lock state (for example, if the first thread holds the read lock of the target resource), the second thread needs to wait for the read lock thread (for example, the first thread) to release the read lock before it can hold the write lock.
[0085] In some embodiments, the second thread may read the first parameter or the second parameter to determine the first target thread.
[0086] The first target thread can be one of the at least one threads indicated by the first parameter. If the at least one thread is arranged in ascending order based on the time sequence of holding the read lock on the target resource, then the first target thread can be the last thread among the at least one thread; if the at least one thread is arranged in ascending order based on the time sequence of holding the read lock on the target resource, then the first target thread can be the first thread among the at least one thread. Alternatively, the first target thread can be the thread indicated by the second parameter.
[0087] Furthermore, the second thread can write the information corresponding to the first target thread into the third parameter. The third parameter is used by the second thread to record the thread holding the read-write lock (e.g., the read lock thread).
[0088] In some embodiments, the first target thread can be a first thread, and the second thread can write the thread information (first information) of the first thread into the third parameter.
[0089] In some embodiments, the second thread may instruct the target processor to run the first target thread (e.g., the first thread) based on a third parameter. In this way, the first target thread can run on the target processor.
[0090] It's important to note that since the second thread isn't removed from the target run queue, and it has the highest priority among those threads, it can be selected by the target processor (or scheduler) as the next thread to run. Furthermore, because the second thread is in a sleep state and doesn't actually run, it can instruct the target processor to run the first target thread (e.g., the first thread). The second thread can act as a proxy for the first target thread, and the target processor actually runs the first target thread. In other words, the first target thread can run on the target processor "as" the second thread. Therefore, when the first thread is running, if there's a thread with a higher priority than the first thread but lower than the second thread (e.g., a third thread), this third thread won't preempt the first thread's CPU resources. This is because the third thread believes the CPU is "actually running" the second thread, and since the second thread's priority is higher than its own, it won't preempt CPU resources. This ensures that the first thread runs smoothly and releases the read lock as soon as possible, allowing the second thread to acquire the write lock quickly. This reduces the time the second thread spends waiting for the write lock and improves its execution efficiency.
[0091] The target run queue of the target processor can refer to a run queue running on a single CPU core. It is understood that a processor (e.g., a CPU) can include one or more cores (also called CPU cores), and each CPU core can run one run queue. Each run queue can include multiple threads waiting to be run. The CPU resources of the threads in the run queue can be allocated based on their priorities, with higher-priority threads having priority in using the CPU (obtaining CPU resources).
[0092] If the first thread holds a read lock on the target resource (for example, if the thread indicated by the first or second parameter is the first thread), the second thread can go to sleep and not be removed from the target run queue.
[0093] In some embodiments, when the read-write lock of the target resource is in a read lock state, a thread waiting for a write lock (e.g., the second thread) can add itself to the waiting queue corresponding to the read-write lock of the target resource. When all read locks of the target resource are released (i.e., all read lock threads release the read-write lock in the read lock state), the last thread to release a read lock (i.e., the last read lock thread to release the read-write lock in the read lock state) can send a wake-up notification to the thread in the waiting queue of the read-write lock of the target resource (e.g., the second thread) to wake up the corresponding thread (e.g., the second thread).
[0094] In some embodiments, before the second thread reads the first parameter or the second parameter for the first time, the waiting queue corresponding to the read-write lock of the target resource is empty. When the second thread reads the first parameter or the second parameter, or after reading the first parameter or the second parameter, it can add itself to (attach) the waiting queue corresponding to the read-write lock of the target resource.
[0095] In some embodiments, when the read-write lock on the target resource is in a read-lock state (e.g., the first thread holds the read lock) and the waiting queue corresponding to the read-write lock is empty, if a thread seeking to hold the read lock arrives (i.e., a new thread (e.g., the fifth thread, the sixth thread) requests to hold the read lock), the second parameter can be continuously updated. This allows the information in the second parameter to be continuously replaced by later-arriving read-lock threads, thus indicating the thread that held the read lock on the target resource the latest (i.e., the latest-arriving read-lock thread).
[0096] In some embodiments, if the waiting queue corresponding to the read-write lock of the target resource is not empty, and a thread arrives with a read lock, the second parameter may not be updated until the thread indicated by the second parameter releases the read lock. This is because, if the waiting queue corresponding to the read-write lock of the target resource is not empty, updating the second parameter requires notifying the thread in the waiting queue (e.g., the second thread) of the updated second parameter so that the thread in the waiting queue (e.g., the second thread) can update its own recorded third parameter. Notifying the thread in the waiting queue (e.g., the second thread) of the updated second parameter incurs overhead. To minimize overhead, if the waiting queue corresponding to the read-write lock of the target resource is not empty, and a thread arrives with a read lock, the second parameter may not be updated until the thread indicated by the second parameter releases the read lock. This avoids frequent updates to the second parameter, preventing unnecessary notification of the updated second parameter to the thread in the waiting queue (e.g., the second thread) (or, avoiding waking up the thread in the waiting queue), thus saving overhead.
[0097] 503. If the first thread releases the read lock on the target resource, the first thread can wake up the second thread.
[0098] In some embodiments, if the thread holding the read lock on the target resource is only the first thread, the second thread can be woken up after the first thread releases the read lock on the target resource.
[0099] In some embodiments, after the first thread releases the read lock on the target resource, the first thread can update the first parameter, and the first information in the updated first parameter is deleted. Further, the first thread determines whether the updated first parameter is null. If the updated first parameter is null, the first thread can wake up the second thread.
[0100] It should be noted that if the first parameter is empty after the update, it means that there are currently no threads holding the read-write lock for the target resource (including read lock threads and write lock threads). In this case, the second thread can be woken up so that the second thread can hold the write lock and then perform write operations on the target resource.
[0101] In some embodiments, if the updated first parameter is empty, the first thread can clear the second parameter. This prevents other threads from misjudging the thread holding the read-write lock on the target resource, thus avoiding impacting the running efficiency of other threads.
[0102] In some embodiments, when the updated first parameter is empty, the second thread can clear the read-write lock's wait queue after waking up the thread in the wait queue. This prevents the next thread holding the read-write lock from accidentally waking up a thread that does not need to wait for the read-write lock.
[0103] In some embodiments, if the updated first parameter is not empty, and if the first thread is the first target thread (the first target thread refers to the thread that holds the read lock on the target resource latest after the second thread first reads the first or second parameter), then the first thread can update the second parameter. The updated second parameter is used to indicate the thread that holds the read lock on the target resource latest among the updated first parameters. This avoids frequent updates to the second parameter and avoids frequently notifying threads in the read-write lock waiting queue (e.g., the second thread) of the updated second parameter (or, in other words, avoids frequently waking up threads in the read-write lock waiting queue), thereby saving overhead.
[0104] In some embodiments, if the updated first parameter is not empty, and if the first thread is the first target thread (the first target thread refers to the thread that holds the read lock on the target resource latest after the second thread first reads the first or second parameter), the first thread can wake up the second thread. After being woken up, the second thread can read the updated first or second parameter and update the first target thread in the third parameter to the second target thread. The second target thread is the thread that holds the read lock on the target resource latest in the updated first parameter (i.e., the second target thread is the thread that holds the read lock on the target resource latest after the second thread is woken up by the first thread and reads (the second time) the first or second parameter). The second thread can notify the target processor to run the second target thread based on the updated third parameter, so that the second target thread runs on the target processor. In this way, the second thread can act as a proxy for the second target thread (e.g., the fourth thread), and the target processor actually runs the second target thread (e.g., the fourth thread). That is, the second target thread (e.g., the fourth thread) can run on the target processor with the "identity" of the second thread. Therefore, when the fourth thread runs, if there is a thread with a higher priority than the fourth thread but lower than the second thread (e.g., the third thread), the third thread will not preempt the CPU resources of the fourth thread. This is because the third thread believes that the CPU is "actually running" the second thread, and since the second thread has a higher priority than the third thread, the third thread will not preempt CPU resources. This ensures that the fourth thread runs smoothly and releases the read lock as soon as possible, allowing the second thread to acquire the write lock quickly, reducing the time the second thread spends waiting for the write lock and improving its execution efficiency.
[0105] 504. The second thread is awakened and holds a write lock on the target resource.
[0106] After the second thread is awakened, it can query the status flag of the read-write lock for the target resource. If the status flag indicates that no thread holds the read-write lock, the second thread can acquire the write lock for the target resource. For example, if the status flag of the read-write lock for the target resource is 0, the second thread can acquire the write lock for the target resource and thus continue running.
[0107] In this embodiment, the thread holding the write lock can be considered to be the thread holding a read-write lock in a write-lock state. The second thread holding the write lock on the target resource means that the second thread holds a read-write lock on the target resource, and this read-write lock is in a write-lock state; that is, the first thread is the write-lock thread. The second thread can perform write operations on the target resource.
[0108] 505. After the second thread finishes running, the target processor schedules the third thread to run.
[0109] The priority of the third thread is lower than that of the second thread, but higher than that of the first thread.
[0110] Referring to the relevant description above (the description of step 502), the first target thread (e.g., the first thread) can run on the target processor as the "second thread". Therefore, when the first thread runs, the third thread considers it to be the "second thread" running. Since the second thread has a higher priority than the third thread, the third thread will not preempt CPU resources. This ensures that the first thread runs smoothly and releases the read lock as soon as possible, allowing the second thread to acquire the write lock quickly, reducing the time the second thread waits for the write lock and improving its execution efficiency. After the second thread finishes running (e.g., the first task is completed), the third thread can run. That is, the third thread runs after the first and second threads have finished running.
[0111] In some embodiments, the third thread is added to the target execution queue while the first thread is running. That is, the third thread is added to the target execution queue after the first thread has started running. In this case, although the third thread has a higher priority than the first thread, the third thread will not preempt the CPU resources of the first thread.
[0112] Based on the method provided in this application, when the first thread holds a read lock on the target resource, the second thread needs to wait for a write lock and can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first thread. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources. This avoids the third thread preempting the first thread's CPU resources, allowing the first thread to execute smoothly and release the read lock as soon as possible. Consequently, the second thread can acquire the write lock as soon as possible, reducing the time the second thread waits for the write lock and improving the execution efficiency of the second thread.
[0113] In some embodiments, step 502 can be replaced by step 511, and step 510 may be included before step 511. Step 503 can be replaced by step 512. Figure 6A As shown, it includes:
[0114] 510. The fourth thread holds a read lock on the target resource.
[0115] In some embodiments, the target run queue further includes a fourth thread that holds a read lock on the target resource.
[0116] After the fourth thread acquires the read lock, it can write the second information into the first parameter. The second information includes the thread identifier of the fourth thread.
[0117] In some embodiments, the fourth thread can arrive before the second thread. That is, the fourth thread holds the read lock earlier than the second thread first queries the first or second parameter. Thus, before the second thread reads the first or second parameter, the first parameter can include the thread identifiers of both the first and fourth threads, and the second parameter can include the thread identifier of either the first or fourth thread. If the fourth thread holds the read lock later than the first thread, the second parameter can indicate the fourth thread; if the first thread holds the read lock later than the fourth thread, the second parameter can indicate the first thread. After reading the first or second parameter, the second thread can determine whether the first target thread is the first or fourth thread and can write the first or fourth thread into the third parameter.
[0118] 511. If the first thread and the fourth thread hold a read lock on the target resource, the second thread enters a sleep state and is not removed from the target run queue.
[0119] In some embodiments, after the second thread queries the first parameter for the first time, it determines that the first thread and the fourth thread hold a read lock on the target resource. In this case, the second thread enters a sleep state and is not removed from the target run queue.
[0120] The remaining descriptions can be found in step 502, and will not be repeated here.
[0121] 512. If both the first thread and the fourth thread release the read lock on the target resource, the first thread or the fourth thread wakes up the second thread.
[0122] In some embodiments, the first thread releases the read lock on the target resource later than the fourth thread. In this case, the fourth thread releases the read lock on the target resource first and can update the first parameter, in which the second information is deleted. Then, the first thread releases the read lock on the target resource. After the first thread releases the read lock on the target resource, it can update the first parameter, in which the first information is deleted. Further, the first thread determines whether the updated first parameter is null. If the updated first parameter is null, the first thread can wake up the second thread.
[0123] In some embodiments, the fourth thread releases the read lock on the target resource later than the first thread. In this case, the first thread releases the read lock on the target resource first and can update the first parameter, in which the first information is deleted. Then, the fourth thread releases the read lock on the target resource. After the fourth thread releases the read lock on the target resource, it can update the first parameter, in which the second information is deleted. Further, the fourth thread determines whether the updated first parameter is null. If the updated first parameter is null, the fourth thread can wake up the second thread.
[0124] It should be noted that if the first parameter is empty after the update, it means that there are currently no threads holding the read-write lock for the target resource (including read lock threads and write lock threads). In this case, the second thread can be woken up so that the second thread can hold the write lock and then perform write operations on the target resource.
[0125] In some embodiments, step 503 can be replaced by step 512, and step 510 may also be included after step 502 and before step 512. Figure 6B As shown, it includes:
[0126] 510. The fourth thread holds a read lock on the target resource.
[0127] In some embodiments, the target run queue further includes a fourth thread that holds a read lock on the target resource.
[0128] After the fourth thread acquires the read lock, it can write the second information into the first parameter. The second information includes the thread identifier of the fourth thread.
[0129] In some embodiments, the fourth thread can arrive after the second thread. That is, the fourth thread holds the read lock later than the second thread first queries the first or second parameter. Thus, before the second thread first reads the first or second parameter, the first parameter only includes the thread identifier of the first thread, and the second parameter includes the thread identifier of the first thread. After reading the first or second parameter, the second thread can determine that the first target thread is the first thread and can write the first thread into the third parameter. Additionally, the second thread can also add itself to the read-write lock's waiting queue.
[0130] After the second thread adds itself to the read-write lock's waiting queue, the fourth thread arrives (the fourth thread can hold the read lock). In this case, the fourth thread can write its own thread information into the first parameter, so that the first parameter can accurately record all read lock threads.
[0131] It should be noted that if the read-write lock's wait queue is not empty, the fourth thread does not need to write its own thread information to the second parameter, i.e., it does not need to update the second parameter. Furthermore, if the thread originally indicated by the second parameter (e.g., the first thread) releases the read lock, and the fourth thread has not yet released the read lock, the second parameter can be updated, changing the first thread indicated by the second parameter to the fourth thread. If the thread originally indicated by the second parameter (e.g., the first thread) releases the read lock, and the fourth thread has also released the read lock, there is no need to update the second parameter. This avoids unnecessarily notifying the thread in the read-write lock's wait queue (e.g., the second thread) of the updated second parameter (or, in other words, avoids waking up the thread in the read-write lock's wait queue), thus saving overhead.
[0132] 512. If both the first thread and the fourth thread release the read lock on the target resource, the first thread or the fourth thread wakes up the second thread.
[0133] Related descriptions and references Figure 6A The relevant explanations will not be repeated here.
[0134] Based on the method provided in this application, when multiple threads (e.g., the first thread and the fourth thread) hold read locks on the target resource, the second thread needs to wait for a write lock and can enter a sleep state. After the second thread enters the sleep state, the target processor can run the first thread and the fourth thread respectively. Furthermore, since the second thread is not removed from the target run queue, threads with lower priority than the second thread (the third thread) in the target run queue will not preempt CPU resources. This avoids the third thread preempting the CPU resources of the first and fourth threads, allowing the first and fourth threads to execute smoothly and release the read locks as soon as possible. Consequently, the second thread can acquire the write lock as soon as possible, reducing the time the second thread waits for the write lock and improving the execution efficiency of the second thread.
[0135] In some embodiments, the target run queue may also include more threads holding read locks on the target resource, such as a fifth thread, a sixth thread, etc. Descriptions of the fifth thread, sixth thread, etc., can be found in the descriptions of the fourth thread and / or the first thread, and will not be repeated here.
[0136] like Figure 7 As shown, taking thread A as the first thread and thread X as the second thread as an example, the thread processing method provided in this application embodiment will be described. The method includes:
[0137] 701. Thread A checks the flag of the read-write lock.
[0138] For example, the parameters corresponding to the read-write lock of the target resource may include flag, owner, waiter_list, and owner_list. For explanations of these parameters, please refer to [link / reference needed]. Figure 5 The relevant descriptions of the embodiments shown are not repeated here.
[0139] For example, before thread A acquires a read lock (i.e., a read-write lock in read lock state), the values of the various parameters of the read-write lock for the target resource can be as follows:
[0140] flag=0, owner=NULL (i.e. empty), waiter_list=empty, owner_list=empty;
[0141] Before thread A acquires the read lock, the number of threads holding the read-write lock is 0; the latest thread to acquire the read lock in owner_list is NULL (i.e., empty), the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock is empty.
[0142] 702. If the flag satisfies the first condition (e.g., flag≥0 and flag<8), thread A holds the read lock.
[0143] For example, the first condition could be that the flag bit of the read-write lock is greater than or equal to 0 and less than a preset value (e.g., 8). That is, when flag ≥ 0 and flag < 8, thread A can hold the read lock (i.e., can perform read operations on the target resource).
[0144] After thread A acquires the read lock, it can write its own thread information to owner_list and owner.
[0145] For example, after thread A acquires the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0146] flag=1, owner=A, waiter_list=empty, owner_list=A;
[0147] That is, after thread A acquires the read lock, the number of threads holding the read-write lock is 1; the thread with the latest read lock acquisition time in owner_list is thread A, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock includes thread A.
[0148] 703. Thread X checks the flag.
[0149] Thread X is the thread that requests to acquire the write lock. Before acquiring the write lock, thread X needs to check the flag and determine whether the flag satisfies the second condition.
[0150] 704a. If the flag does not meet the second condition (e.g., the flag is not 0), thread X enters a sleep state and is not removed from the target run queue.
[0151] For example, the second condition could be that the read-write lock's flag bit is 0. That is, when the read-write lock's flag bit is not 0 (for example, flag = 1), it is considered that the second condition is not met, and thread X cannot hold the write lock temporarily (i.e., cannot perform write operations on the target resource), and can only hold the write lock after other threads holding read locks release their read locks.
[0152] 704b. Set X.owner for thread X (for example, write thread information of thread A to X.owner).
[0153] If the flag does not meet the second condition, thread X can set X.owner. For example, if the threads in owner_list are arranged in ascending order based on the time they hold the read lock on the target resource, the thread information corresponding to first_owner in owner_list or the thread information corresponding to owner (e.g., thread information of thread A) can be written to X.owner.
[0154] 704c, Thread X notifies the target processor to run thread A based on X.owner.
[0155] That is, thread X acts as a proxy for thread A, causing the target processor to actually run thread A.
[0156] Thus, since thread X is not removed from the target run queue, and thread X is the highest priority thread in the target run queue, thread X can be selected by the target processor (also known as the scheduler) as the next thread to run (soon to run). Furthermore, since thread X enters a sleep state and does not actually run, thread X can notify the target processor to run the first target thread (e.g., thread A). Thread X can act as a proxy for the first target thread (e.g., thread A), and the target processor actually runs the first target thread (e.g., thread A). That is, the first target thread (e.g., thread A) can run on the target processor "as" thread X.
[0157] Since the first target thread (e.g., thread A) runs on the target processor "as" thread X, when thread A runs, thread Y perceives it as "thread X" running. Because thread X has a higher priority than thread Y, thread Y will not preempt CPU resources. This ensures that thread A runs smoothly and releases the read lock as quickly as possible, allowing thread X to acquire the write lock quickly, reducing the time thread X spends waiting for the write lock and improving its execution efficiency. After thread X finishes running (e.g., the first task is completed), thread Y can run. In other words, thread Y runs after threads A and X have finished running.
[0158] 705. Thread X is added to the waiter_list of the read-write lock.
[0159] If the flag does not meet the second condition, thread X can add itself to the waiter_list of read-write locks. Then, when all read locks on the target resource are released, the last thread to release a read lock can send a wake-up notification to a thread in the waiter_list (e.g., thread X) to wake up the corresponding thread (e.g., thread X).
[0160] For example, after thread X is added to the waiter_list of the read-write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0161] flag=1, owner=A, waiter_list=X, owner_list=A;
[0162] That is, after thread A acquires the read lock, the number of threads holding the read-write lock is 1; the thread with the latest read lock acquisition time in owner_list is thread A, the waiting queue for the read-write lock includes thread X, and the queue of threads holding the read-write lock includes thread A.
[0163] In this embodiment, steps 704b-705 can be executed before step 704a, and there is no necessary execution order between steps 704b-705. This embodiment does not make specific limitations on the execution order between steps 704b-705.
[0164] 706. Thread A releases the read lock.
[0165] After thread A releases the read lock, it can update the flag. For example, it can change the value of the flag from 1 to 0.
[0166] Optionally, after thread A releases the read lock, it can remove its own information from the owner_list.
[0167] Optionally, after thread A removes its own information from the owner_list, if the owner_list is empty, thread A can clear the owner. This can prevent other threads from misjudging the thread holding the read-write lock of the target resource and avoid affecting the running efficiency of other threads.
[0168] 707. Thread A checks the flag. If the flag meets the second condition (for example, the flag is 0), it wakes up thread X.
[0169] After thread A updates the flag, it can check if the flag meets the second condition. If the flag meets the second condition, it means that thread A is the last thread to release the read lock, and thread A can wake up thread X based on the waiter_list.
[0170] For example, the second condition could be that the read-write lock's flag bit is 0. When flag is 0, the second condition is considered to be met. A flag meeting the second condition indicates that the number of threads holding the read-write lock is 0, meaning no thread holds the read-write lock. In this case, thread A can wake up thread X so that thread X can acquire the write lock promptly.
[0171] After thread A wakes up thread X, it can clear the waiter_list. This prevents the next thread holding the read-write lock from accidentally waking up threads that do not need to wait for the read-write lock.
[0172] For example, after thread A wakes up thread X, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0173] flag=0, owner=empty, waiter_list=empty, owner_list=empty;
[0174] That is, after thread A acquires the read lock, the number of threads holding the read-write lock is 0; the thread with the latest read lock acquisition time in owner_list is empty, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock is empty.
[0175] 708. Thread X checks the flag.
[0176] After thread X is awakened, it can check the flag and determine whether the flag meets the second condition.
[0177] 709. Thread X holds the write lock if the second condition is met (e.g., the flag is 0).
[0178] In some embodiments, if the flag satisfies the second condition, thread X can clear X.owner.
[0179] For example, after thread X acquires the write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0180] flag=1, owner=X, waiter_list=empty, owner_list=X;
[0181] That is, after thread X acquires the write lock, the number of threads holding the read-write lock is 1; the thread with the latest read lock acquisition time in owner_list is thread X, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock includes thread X.
[0182] 710. Thread X releases the write lock.
[0183] After thread X completes its task, it can release the write lock.
[0184] For example, after thread X releases the write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0185] flag=0, owner=empty, waiter_list=empty, owner_list=empty;
[0186] That is, after thread X releases the write lock, the number of threads holding the read-write lock is 0; the number of threads holding the read-write lock is empty, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock is empty.
[0187] 711. After thread X releases the write lock, it checks the wait queue (waiter_list) of the read-write lock. If waiter_list is empty, thread X does not need to wake up other threads.
[0188] Based on the method provided in this application, when thread A holds a read lock on the target resource, thread X can enter a sleep state. After thread X enters the sleep state, the target processor can run thread A. Furthermore, since thread X is not removed from the target run queue, threads with lower priority than thread X in the target run queue (e.g., thread Y) will not preempt CPU resources, thus preventing thread Y from preempting thread A's CPU resources. This allows thread A to execute smoothly and release the read lock as soon as possible. Consequently, thread X can acquire a write lock as quickly as possible, reducing the time thread X waits for the write lock and improving thread X's execution efficiency.
[0189] like Figure 8 As shown, taking thread A as the first thread, thread X as the second thread, and threads holding write locks including a fourth thread (e.g., thread B) and a fifth thread (e.g., thread C) as an example, the thread processing method provided in this application embodiment will be described. The method includes:
[0190] 801a. Thread A checks the flag of the read-write lock.
[0191] 802a. If the flag satisfies the first condition (e.g., flag≥0 and flag<8), thread A holds the read lock.
[0192] Steps 801a-802a can be referred to the relevant descriptions of steps 701-702, and will not be repeated here.
[0193] 801b. Thread B checks the flag of the read-write lock.
[0194] 802b. If the flag satisfies the first condition (e.g., flag≥0 and flag<8), thread B holds the read lock.
[0195] For example, after thread B acquires the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0196] flag=2, owner=B, waiter_list=empty, owner_list=B->A;
[0197] After thread B acquires the read lock, the number of threads holding the read-write lock is 2. Among the threads currently holding the read-write lock, thread B is the last to acquire the read lock, and the wait queue for the read-write lock is NULL (empty). The queue of threads holding the read-write lock includes thread A and thread B. The threads in `owner_list` are arranged in ascending order based on the time they acquired the read lock on the target resource; therefore, thread B can be placed before thread A.
[0198] Alternatively, the threads in owner_list can be arranged sequentially from earliest to latest based on the time they hold the read lock on the target resource. In this case, thread B can be arranged after thread A.
[0199] 801c, Thread C checks the flag of the read-write lock.
[0200] 802c. If the flag satisfies the first condition (e.g., flag≥0 and flag<8), thread C holds the read lock.
[0201] For example, after thread C acquires the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0202] flag=3, owner=C, waiter_list=empty, owner_list=C->B->A;
[0203] After thread C acquires the read lock, the number of threads holding the read-write lock is 3. Among the threads currently holding the read-write lock, thread C is the last to acquire the read lock, and the wait queue for the read-write lock is NULL (empty). The queue of threads holding the read-write lock includes threads A, B, and C. The threads in `owner_list` are arranged in ascending order based on the time they acquired the read lock on the target resource; therefore, thread C can be placed before thread B, and thread B can be placed before thread A.
[0204] Alternatively, the threads in owner_list can be arranged sequentially from earliest to latest based on the time they hold the read lock on the target resource. In this case, thread C can be arranged after thread B, and thread B can be arranged after thread A.
[0205] 803. Thread X checks the flag.
[0206] Thread X can arrive after threads A, B, and C have acquired the read lock, and then attempt to acquire the write lock. Thread X can first check the read-write lock's flag to determine if the flag satisfies the second condition (e.g., the flag is not 0).
[0207] 804a. If the flag does not meet the second condition (e.g., the flag is not 0), thread X enters a sleep state and is not removed from the target run queue.
[0208] 804b. Set X.owner for thread X (for example, write thread information of thread C to X.owner).
[0209] If the flag does not meet the second condition, thread X can set X.owner. For example, if the threads in owner_list are arranged in ascending order based on the time they hold the read lock on the target resource, the thread information corresponding to first_owner in owner_list or the thread information corresponding to owner (e.g., the thread information of thread C) can be written to X.owner.
[0210] 804c. Thread X notifies the target processor to run thread C based on X.owner. That is, thread X acts as a proxy for thread C, so that the target processor actually runs thread C.
[0211] Thus, since thread X is not removed from the target run queue, and thread X is the highest priority thread in the target run queue, thread X can be selected by the target processor (also known as the scheduler) as the next thread to run (soon to run). Furthermore, since thread X enters a sleep state and does not actually run, thread X can notify the target processor to run the first target thread (e.g., thread C). Thread X can act as a proxy for the first target thread (e.g., thread C), and the target processor actually runs the first target thread (e.g., thread C). That is, the first target thread (e.g., thread C) can run on the target processor "as" thread X.
[0212] Since the first target thread (e.g., thread C) runs on the target processor "as" thread X, when thread C runs, thread Y perceives it as "thread X" running. Because thread X has a higher priority than thread Y, thread Y will not preempt CPU resources. This ensures that thread C runs smoothly and releases the read lock as quickly as possible, allowing thread X to acquire the write lock quickly, reducing the time thread X spends waiting for the write lock and improving its execution efficiency. After thread X finishes running (e.g., the first task is completed), thread Y can run. In other words, thread Y runs after threads C and X have finished running.
[0213] 805. Thread X is added to the waiter_list of the read-write lock.
[0214] In this embodiment, steps 804b-805 can be executed before step 804a, and there is no necessary execution order between steps 804b-805. This embodiment does not make specific limitations on the execution order between steps 804b-805.
[0215] For example, after thread X is added to the waiter_list of the read-write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0216] flag=3, owner=C, waiter_list=X, owner_list=C->B->A;
[0217] That is, after thread X is added to the waiter_list of the read-write lock, the wait queue of the read-write lock includes thread X, and the values of other parameters remain unchanged.
[0218] 806a. Thread A releases the read lock.
[0219] After thread A releases the read lock, it can update the flag. For example, it can change the value of the flag from 3 to 2.
[0220] Optionally, after thread A releases the read lock, it can remove its own information from the owner_list.
[0221] For example, after thread A releases the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0222] flag=2, owner=C, waiter_list=X, owner_list=C->B;
[0223] That is, after thread A releases the read lock, the number of threads holding the read-write lock is 2; the thread with the latest read lock time in owner_list is thread C, the waiting queue of the read-write lock includes thread X, and the queue of threads holding the read-write lock includes thread C and thread B.
[0224] 806b. Thread A checks the flag. If the flag does not meet the second condition (e.g., the flag is 0), it does not wake up thread X.
[0225] 806c, Thread B releases the read lock.
[0226] After thread B releases the read lock, it can update the flag. For example, it can change the value of the flag from 2 to 1.
[0227] Optionally, after thread B releases the read lock, it can remove its own information from the owner_list.
[0228] For example, after thread B releases the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0229] flag=1, owner=C, waiter_list=X, owner_list=C;
[0230] That is, after thread B releases the read lock, the number of threads holding the read-write lock is 1; the thread with the latest read lock time in owner_list is thread C, the waiting queue of the read-write lock includes thread X, and the queue of threads holding the read-write lock includes thread C.
[0231] 806d. Thread B checks the flag. If the flag does not meet the second condition (for example, the flag is 0), it does not wake up thread X.
[0232] 806e, Thread C releases the read lock.
[0233] After thread C releases the read lock, it can update the flag. For example, it can change the value of the flag from 1 to 0.
[0234] Optionally, after thread C releases the read lock, it can remove its own information from the owner_list.
[0235] For example, after thread C releases the read lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0236] flag=0, owner=empty, waiter_list=X, owner_list=empty;
[0237] That is, after thread C releases the read lock, the number of threads holding the read-write lock is 0; the thread with the latest read lock time in owner_list is empty; the waiting queue for the read-write lock includes thread X; and the queue of threads holding the read-write lock is empty.
[0238] 807. Thread C checks the flag. If the flag meets the second condition (e.g., the flag is 0), thread X is woken up.
[0239] After thread C updates the flag, it can determine whether the flag satisfies the second condition. If the flag satisfies the second condition (e.g., flag is 0), it means that thread C is the last thread to release the read lock, and thread C can wake up thread X based on the waiter_list.
[0240] For example, after thread C wakes up thread X, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0241] flag=0, owner=empty, waiter_list=empty, owner_list=empty;
[0242] That is, after thread C wakes up thread X, it can clear the wait queue of the read-write lock.
[0243] In some embodiments, when the target owner in the owner_list queue finishes holding the lock, if one or more owners remain in the owner_list queue, the owner with the latest lock read time among the remaining one or more owners can be notified to the threads in the wait_list (e.g., thread X), so that the threads in the wait_list (e.g., thread X) can update their own recorded owner (e.g., X.owner). Here, the target owner refers to the thread (e.g., thread C) that holds the read lock on the target resource the latest after thread X first reads the owner_list or the owner. In this way, compared to the scheme where the wait_list threads (e.g., thread X) are notified to update their own recorded owner (e.g., X.owner) after each owner update, the above method reduces the number of times the thread in the wait_list is notified to update its owner, thereby reducing overhead.
[0244] 808. Thread X checks the flag.
[0245] After thread X is awakened, it can check the flag and determine whether the flag meets the second condition.
[0246] 809. If the flag satisfies the second condition (e.g., the flag is 0), thread X holds the write lock.
[0247] For example, after thread X acquires the write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0248] flag=1, owner=X, waiter_list=empty, owner_list=X;
[0249] That is, after thread X acquires the write lock, the number of threads holding the read-write lock is 1; the thread with the latest read lock acquisition time in owner_list is thread X, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock includes thread X.
[0250] 810. Thread X releases the write lock.
[0251] After thread X completes its task, it can release the write lock.
[0252] For example, after thread X releases the write lock, the values of the various parameters of the read-write lock for the target resource can be as follows:
[0253] flag=0, owner=empty, waiter_list=empty, owner_list=empty;
[0254] That is, after thread X releases the write lock, the number of threads holding the read-write lock is 0; the number of threads holding the read-write lock is empty, the wait queue for the read-write lock is empty, and the queue of threads holding the read-write lock is empty.
[0255] 811. After thread X releases the write lock, it checks the wait queue (waiter_list) of the read-write lock. If waiter_list is empty, thread X does not need to wake up other threads.
[0256] Based on the method provided in this application, when multiple threads (e.g., thread A, thread B, and thread C) hold read locks on a target resource, thread X needs to wait for a write lock and can enter a sleep state. After thread X enters the sleep state, the target processor can run threads A, B, and C respectively. Furthermore, since thread X is not removed from the target run queue, threads with lower priority than thread X (thread Y) in the target run queue will not preempt CPU resources. This avoids thread Y preempting the CPU resources of threads A, B, and C, allowing threads A, B, and C to execute smoothly and release read locks as soon as possible. Consequently, thread X can acquire a write lock as quickly as possible, reducing the time thread X waits for a write lock and improving the execution efficiency of thread X.
[0257] The above embodiments ( Figures 5-8 The illustrated embodiment uses the example of a second thread (e.g., thread X) waiting for a write lock. In some embodiments, the first thread may be a write lock thread, and the second thread may be a read lock thread. In this case, if a priority inversion problem occurs, the method for resolving the mutex priority inversion problem described above can be referred to, and will not be repeated here.
[0258] The method provided in this application has stronger generalization compared to solutions such as priority inheritance and priority ceiling, meaning it can be applied to a wider range of scenarios. Priority inheritance and priority ceiling solutions solve the high-priority inversion problem by increasing the priority of low-priority threads, and are only applicable to scenarios where CPU resource allocation for threads is based on thread priority. The method provided in this application, however, uses a high-priority thread (e.g., thread A) as a proxy for a low-priority thread (e.g., thread C). In scenarios where CPU resource allocation is based on thread priority, this prevents other threads (medium-priority threads, such as thread B) from preempting the CPU resources of low-priority threads, thus solving the high-priority inversion problem. Furthermore, in scenarios where CPU resource scheduling is based on time-sharing mechanisms, using a high-priority thread as a proxy for a low-priority thread allows the low-priority thread to run not only in its own time slice but also in the time slice of the high-priority thread. This improves the running efficiency of the low-priority thread, ensures its smooth operation, and reduces the waiting time of the high-priority thread.
[0259] The method provided in the above embodiments can be applied to electronic devices. Figure 9 This is a schematic diagram of the structure of an electronic device 100 provided in an embodiment of this application.
[0260] like Figure 9As shown, the electronic device 100 may include a processor 110, an external memory interface 120, an internal memory 121, a universal serial bus (USB) interface 130, a charging management module 140, a power management module 141, a battery 142, an antenna 1, an antenna 2, a mobile communication module 150, a wireless communication module 160, an audio module 170, a speaker 170A, a receiver 170B, a microphone 170C, a headphone jack 170D, a sensor module 180, buttons 190, a motor 191, an indicator 192, a camera 193, a display screen 194, and a subscriber identification module (SIM) card interface 195, etc.
[0261] The sensor module 180 may include a pressure sensor 180A, a gyroscope sensor 180B, a barometric pressure sensor 180C, a magnetic sensor 180D, an accelerometer sensor 180E, a distance sensor 180F, a proximity sensor 180G, a fingerprint sensor 180H, a temperature sensor 180J, a touch sensor 180K, an ambient light sensor 180L, a bone conduction sensor 180M, etc.
[0262] It is understood that the structure illustrated in this embodiment does not constitute a specific limitation on the electronic device 100. In other embodiments, the electronic device 100 may include more or fewer components than illustrated, or combine some components, or split some components, or have different component arrangements. The illustrated components may be implemented in hardware, software, or a combination of software and hardware.
[0263] Processor 110 may include one or more processing units, such as: application processor (AP), modem processor, graphics processing unit (GPU), image signal processor (ISP), controller, memory, video codec, digital signal processor (DSP), baseband processor, and / or neural network processing unit (NPU), etc. Different processing units may be independent devices or integrated into one or more processors.
[0264] As one embodiment, processor 110 may include one or more CPUs. The target processor may be one of these CPUs.
[0265] In this embodiment, the target processor can allocate resources to each thread based on their priority. A target run queue can run on the target processor, which can refer to a run queue running on a CPU core. It is understood that a processor (e.g., a CPU) can include one or more cores (also called CPU cores), and each CPU core can run a run queue. Each run queue can include multiple threads waiting to be run. Threads in the run queue can have their CPU resources allocated based on their priority; threads with higher priority can use the CPU first (obtain CPU resources).
[0266] The controller can be the nerve center and command center of the electronic device 100. The controller can generate operation control signals according to the instruction opcode and timing signals to complete the control of fetching and executing instructions.
[0267] The processor 110 may also include a memory for storing instructions and data. In some embodiments, the memory in the processor 110 is a cache memory. This memory can store instructions or data that the processor 110 has just used or that are used repeatedly. If the processor 110 needs to use the instruction or data again, it can retrieve it directly from the memory. This avoids repeated accesses, reduces the waiting time of the processor 110, and thus improves the efficiency of the system.
[0268] In some embodiments, the processor 110 may include one or more interfaces. Interfaces may include an inter-integrated circuit (I2C) interface, an inter-integrated circuit sound (I2S) interface, a pulse code modulation (PCM) interface, a universal asynchronous receiver / transmitter (UART) interface, a mobile industry processor interface (MIPI), a general-purpose input / output (GPIO) interface, a subscriber identity module (SIM) interface, and / or a universal serial bus (USB) interface, etc.
[0269] It is understood that the interface connection relationships between the modules illustrated in this embodiment are merely illustrative and do not constitute a structural limitation on the electronic device 100. In other embodiments, the electronic device 100 may also employ different interface connection methods or combinations of multiple interface connection methods as described in the above embodiments.
[0270] The charging management module 140 receives charging input from the charger. While charging the battery 142, the charging management module 140 can also supply power to electronic devices through the power management module 141.
[0271] The power management module 141 connects the battery 142, the charging management module 140, and the processor 110. The power management module 141 receives input from the battery 142 and / or the charging management module 140 to power the processor 110, internal memory 121, external memory, display screen 194, camera 193, and wireless communication module 160, etc. In some other embodiments, the power management module 141 may also be located within the processor 110. In other embodiments, the power management module 141 and the charging management module 140 may be located in the same device.
[0272] The wireless communication function of electronic device 100 can be realized through antenna 1, antenna 2, mobile communication module 150, wireless communication module 160, modem processor and baseband processor, etc.
[0273] Antenna 1 and antenna 2 are used to transmit and receive electromagnetic wave signals. Each antenna in electronic device 100 can be used to cover one or more communication frequency bands. Different antennas can also be reused to improve antenna utilization. For example, antenna 1 can be reused as a diversity antenna for a wireless local area network.
[0274] The mobile communication module 150 can provide solutions for wireless communication, including 2G / 3G / 4G / 5G, applied to the electronic device 100. The mobile communication module 150 may include at least one filter, switch, power amplifier, low noise amplifier (LNA), etc. The mobile communication module 150 can receive electromagnetic waves via antenna 1, and perform filtering, amplification, and other processing on the received electromagnetic waves before transmitting them to a modem processor for demodulation. The mobile communication module 150 can also amplify the signal modulated by the modem processor and convert it into electromagnetic waves for radiation via antenna 1.
[0275] The modem processor may include a modulator and a demodulator. The modulator modulates the low-frequency baseband signal to be transmitted into a mid-to-high frequency signal. The demodulator demodulates the received electromagnetic wave signal into a low-frequency baseband signal. The demodulator then transmits the demodulated low-frequency baseband signal to the baseband processor for processing. After processing by the baseband processor, the low-frequency baseband signal is transmitted to the application processor. The application processor outputs sound signals through audio devices (not limited to speaker 170A, receiver 170B, etc.) or displays images or videos through the display screen 194.
[0276] The wireless communication module 160 can provide solutions for wireless communication applications on the electronic device 100, including wireless local area networks (WLANs) (such as wireless fidelity (Wi-Fi) networks), Bluetooth (BT), global navigation satellite system (GNSS), frequency modulation (FM), near field communication (NFC), and infrared (IR) technologies. The wireless communication module 160 can be one or more devices integrating at least one communication processing module. The wireless communication module 160 receives electromagnetic waves via antenna 2, performs frequency modulation and filtering of the electromagnetic wave signals, and sends the processed signal to processor 110. The wireless communication module 160 can also receive signals to be transmitted from processor 110, perform frequency modulation and amplification, and convert them into electromagnetic waves for radiation via antenna 2.
[0277] In some embodiments, antenna 1 of electronic device 100 is coupled to mobile communication module 150, and antenna 2 is coupled to wireless communication module 160, enabling electronic device 100 to communicate with networks and other devices via wireless communication technology. The wireless communication technology may include Global System for Mobile Communications (GSM), General Packet Radio Service (GPRS), Code Division Multiple Access (CDMA), Wideband Code Division Multiple Access (WCDMA), Time-Division Code Division Multiple Access (TD-SCDMA), Long Term Evolution (LTE), BT, GNSS, WLAN, NFC, FM, and / or IR technologies, etc. The GNSS may include the Global Positioning System (GPS), the Global Navigation Satellite System (GLONASS), the BeiDou Navigation Satellite System (BDS), the Quasi-Zenith Satellite System (QZSS), and / or satellite-based augmentation systems (SBAS).
[0278] Electronic device 100 implements display functions through a GPU, a display screen 194, and an application processor. The GPU is a microprocessor for image processing, connected to the display screen 194 and the application processor. The GPU is used to perform mathematical and geometric calculations and for graphics rendering. Processor 110 may include one or more GPUs, which execute program instructions to generate or modify display information.
[0279] Display screen 194 is used to display images, videos, etc. Display screen 194 includes a display panel. The display panel can be a liquid crystal display (LCD), a light-emitting diode (LED), an organic light-emitting diode (OLED), an active-matrix organic light-emitting diode (AMOLED), a flexible light-emitting diode (FLED), a MiniLED, a MicroLED, a Micro-OLED, a quantum dot light-emitting diode (QLED), etc.
[0280] Electronic device 100 can perform shooting functions through an ISP, camera 193, video codec, GPU, display screen 194, and application processor. The ISP processes data fed back from the camera 193. The camera 193 captures still images or video. The digital signal processor processes digital signals, including digital image signals and other digital signals. The video codec compresses or decompresses digital video. Electronic device 100 can support one or more video codecs. Thus, electronic device 100 can play or record video in various encoding formats, such as Moving Picture Experts Group (MPEG) 1, MPEG 2, MPEG 3, MPEG 4, etc.
[0281] Camera 193 can include 1 to N cameras. For example, an electronic device may include 2 front-facing cameras and 4 rear-facing cameras. NPU stands for Neural Network (NN) computing processor. By borrowing the structure of biological neural networks, such as the transmission patterns between neurons in the human brain, it can quickly process input information and continuously learn on its own. Through NPU, intelligent cognitive applications such as image recognition, facial recognition, speech recognition, and text understanding can be realized in electronic device 100.
[0282] The external memory interface 120 can be used to connect an external memory card, such as a Micro SD card, to expand the storage capacity of the electronic device 100. The external memory card communicates with the processor 110 through the external memory interface 120 to achieve data storage functionality. For example, music, video, and other files can be saved on the external memory card. The internal memory 121 can be used to store computer executable program code, which includes instructions. The processor 110 executes various functional applications and data processing of the electronic device 100 by running the instructions stored in the internal memory 121. For example, in this embodiment, the processor 110 can execute instructions stored in the internal memory 121, which may include a program storage area and a data storage area. The program storage area may store the operating system, at least one application program required for a function (such as sound playback function, image playback function, etc.), etc. The data storage area may store data created during the use of the electronic device 100 (such as audio data, phone book, etc.). In addition, the internal memory 121 may include high-speed random access memory, and may also include non-volatile memory, such as at least one disk storage device, flash memory device, universal flash storage (UFS), etc.
[0283] Electronic device 100 can implement audio functions, such as music playback and recording, through audio module 170, speaker 170A, receiver 170B, microphone 170C, headphone jack 170D, and application processor.
[0284] Audio module 170 is used to convert digital audio information into analog audio signal output, and also to convert analog audio input into digital audio signal. Audio module 170 can also be used for audio signal encoding and decoding. Speaker 170A, also called a "loudspeaker," is used to convert audio electrical signals into sound signals. Receiver 170B, also called a "handset," is used to convert audio electrical signals into sound signals. Microphone 170C, also called a "microphone" or "microphone unit," is used to convert sound signals into electrical signals. Headphone jack 170D is used to connect wired headphones.
[0285] Buttons 190 include a power button, volume buttons, etc. Buttons 190 can be mechanical buttons or touch buttons. Electronic device 100 can receive button input and generate key signal inputs related to user settings and function control. Motor 191 can generate vibration alerts. Motor 191 can be used for incoming call vibration alerts or for touch vibration feedback. Indicator 192 can be an indicator light, used to indicate charging status, battery level changes, messages, missed calls, notifications, etc. SIM card interface 195 is used to connect a SIM card. The SIM card can be inserted into or removed from the SIM card interface 195 to achieve contact and separation with electronic device 100. Electronic device 100 can support one or N SIM card interfaces, where N is a positive integer greater than 1. SIM card interface 195 can support Nano SIM cards, Micro SIM cards, SIM cards, etc.
[0286] The methods described in the above embodiments can all be implemented in the electronic device 100 having the above hardware structure.
[0287] Some embodiments of this application provide an electronic device that may include a touchscreen, a memory, and one or more processors. The touchscreen, memory, and processors are coupled. The memory stores computer program code, which includes computer instructions. When the processor executes the computer instructions, the electronic device can perform various functions or steps performed by the electronic device in the above method embodiments. The structure of the electronic device can be referred to... Figure 9 The structure of the electronic device 100 shown.
[0288] This application also provides a chip system (e.g., a system-on-a-chip (SoC)). Figure 10 As shown, the chip system includes at least one processor 1001 and at least one interface circuit 1002. The processor 1001 and the interface circuit 1002 are interconnected via lines. For example, the interface circuit 1002 can be used to receive signals from other devices (e.g., the memory of an electronic device). As another example, the interface circuit 1002 can be used to send signals to other devices (e.g., the processor 1001 or the touchscreen of an electronic device). Exemplarily, the interface circuit 1002 can read instructions stored in the memory and send those instructions to the processor 1001. When the instructions are executed by the processor 1001, the electronic device can perform the steps in the above embodiments. Of course, the chip system may also include other discrete components, which are not specifically limited in this application embodiment.
[0289] This application also provides a computer-readable storage medium including computer instructions that, when executed on the aforementioned electronic device, cause the electronic device to perform the functions described in the method embodiment (e.g., ...). Figure 9 The various functions or steps performed by the electronic device 100 shown.
[0290] This application also provides a computer program product that, when run on an electronic device, causes the electronic device to perform the above-described method embodiments (e.g., Figure 9 The various functions or steps performed by the electronic device 100 shown.
[0291] Through the above description of the embodiments, those skilled in the art can clearly understand that, for the sake of convenience and brevity, only the division of the above functional modules is used as an example. In actual applications, the above functions can be assigned to different functional modules as needed, that is, the internal structure of the device can be divided into different functional modules to complete all or part of the functions described above.
[0292] In the several embodiments provided in this application, it should be understood that the disclosed apparatus and methods can be implemented in other ways. For example, the apparatus embodiments described above are merely illustrative; for instance, the division of modules or 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 device, or some features may be ignored or not executed. Furthermore, the mutual coupling or direct coupling or communication connection shown or discussed may be through some interfaces; the indirect coupling or communication connection between devices or units may be electrical, mechanical, or other forms.
[0293] The units described as separate components may or may not be physically separate. A component shown as a unit can be one or more physical units; that is, it can be located in one place or distributed in multiple different locations. Some or all of the units can be selected to achieve the purpose of this embodiment according to actual needs.
[0294] Furthermore, 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. The integrated unit can be implemented in hardware or as a software functional unit.
[0295] If the integrated unit is implemented as a software functional unit and sold or used as an independent product, it can be stored in a readable storage medium. Based on this understanding, the technical solutions of the embodiments of this application, essentially or in other words, the parts that contribute to the prior art, or all or part of the technical solutions, can be embodied in the form of a software product. This software product is stored in a storage medium and includes several instructions to cause a device (which may be a microcontroller, chip, etc.) or processor 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.
[0296] The above description is merely a specific embodiment of this application, but the scope of protection of this application is not limited thereto. Any variations or substitutions within the technical scope disclosed in this application should be included within the scope of protection of this application. Therefore, the scope of protection of this application should be determined by the scope of the claims.
Claims
1. A method for processing threads, characterized in that, Applied to an electronic device, the electronic device including a target processor, the target processor including a target run queue, the target run queue including a first thread, a second thread, and a third thread, the method includes: While the first thread holds a read lock on the target resource, the second thread enters a sleep state and is not removed from the target run queue. The second thread is selected by the target processor as the next thread to run, and the second thread notifies the target processor to run the first thread. If the first thread releases the read lock on the target resource, the second thread is awakened and acquires the write lock on the target resource. After the second thread finishes running, the third thread starts running. The priority of the third thread is lower than that of the second thread, but higher than that of the first thread.
2. The method according to claim 1, characterized in that, Before the second thread enters a sleep state and is removed from the target run queue, the method further includes: The second thread reads either a first parameter or a second parameter. The first parameter indicates at least one thread holding the read lock on the target resource. The at least one thread is arranged sequentially based on the time order in which it holds the read lock on the target resource, and the at least one thread includes the first thread. The second parameter indicates a first target thread, which is the thread among the at least one threads that holds the read lock on the target resource the latest.
3. The method according to claim 2, characterized in that, The method further includes: The second thread writes the information corresponding to the first target thread into the third parameter; The second thread notifies the target processor to run the first target thread based on the third parameter; The first target thread runs on the target processor.
4. The method according to claim 2, characterized in that, Before the second thread reads the first parameter or the second parameter, the method further includes: The first thread writes first information into the first parameter and the second parameter, wherein the first information includes the thread identifier of the first thread.
5. The method according to claim 4, characterized in that, After the first thread releases the read lock on the target resource, the method further includes: The first thread updates the first parameter, and the first information in the updated first parameter is deleted. The first thread determines whether the first parameter updated by the first thread is empty; If the first parameter updated by the first thread is empty, the first thread wakes up the second thread.
6. The method according to claim 5, characterized in that, The method further includes: If the first parameter is empty after being updated by the first thread, the first thread clears the second parameter.
7. The method according to claim 5, characterized in that, The method further includes: If the first parameter updated by the first thread is not empty and the first thread is the first target thread, the first thread updates the second parameter. The second parameter updated by the first thread is used to indicate the thread that holds the read lock on the target resource the latest among the first parameters updated by the first thread.
8. The method according to claim 5 or 7, characterized in that, The method further includes: If the first parameter updated by the first thread is not empty and the first thread is the first target thread, the first thread wakes up the second thread. The second thread reads the first parameter updated by the first thread or the second parameter updated by the first thread, and updates the first target thread in the third parameter to the second target thread. The second target thread is the thread that holds the read lock on the target resource the latest in the first parameter updated by the first thread. The second thread notifies the target processor to run the second target thread based on the updated third parameter; The second target thread runs on the target processor.
9. The method according to any one of claims 5-7, characterized in that, After the second thread reads the first parameter or the second parameter, the method further includes: The second thread adds itself to the waiting queue; The first thread waking up the second thread includes: The first thread wakes up the second thread based on the waiting queue.
10. The method according to any one of claims 2-7, characterized in that, The target run queue also includes a fourth thread, which holds a read lock on the target resource. The second thread being awakened when the first thread releases the read lock on the target resource includes: The second thread is awakened when both the first thread and the fourth thread release the read lock on the target resource.
11. The method according to claim 10, characterized in that, The method further includes: The fourth thread writes the second information into the first parameter and the second parameter, and the second information includes the thread identifier of the fourth thread.
12. The method according to claim 11, characterized in that, After the fourth thread releases the read lock on the target resource, the method further includes: The fourth thread updates the first parameter, and the second information in the updated first parameter is deleted. The fourth thread determines whether the first parameter updated by the fourth thread is empty; If the first parameter updated by the fourth thread is empty, the fourth thread wakes up the second thread.
13. An electronic device, characterized in that, The electronic device includes: a wireless communication module, a memory, and one or more processors; the wireless communication module, the memory, and the processor are coupled together. The memory is used to store computer program code, which includes computer instructions; when the computer instructions are executed by the processor, the electronic device performs the method as described in any one of claims 1-12.
14. A computer-readable storage medium, characterized in that, Includes computer instructions; When the computer instructions are executed on an electronic device, the electronic device causes the electronic device to perform the method as described in any one of claims 1-12.