iOS semaphore causes thread priority inversion | JD Cloud technical team

Using semaphores in concurrent queues may cause thread priority inversion

1. Encountered on iOS16 & XCode14 - Reminder of thread priority inversion caused by using semaphores



After querying the information, I found that tools have been added to XCode14, such as:

Thread Performance Checker (enabled by default on XCode14). This tool will allow the APP to find problems such as thread priority inversion and non-UI work running on the main thread when running. It will be displayed in the XCode problem navigation bar. The lag risk warning is prompted in the system, which can help us discover and solve the hidden lag risk problem in the early stage of development; this is not a crash. If you don’t want it, you can remove it in the Diagnostics of "Product -> Scheme -> Edit Scheme Thread Performance Checker checked"



XCode14 also has some other newly added tool classes, please refer to iOS stuck detection

2. About thread priority inversion

Priority inversion (Poiority Inversion) means that high-priority tasks need to wait for low-priority tasks to complete before they can continue execution. In this case, the priority is inverted.

Example: There are three threads: A, B, C. Priority level A > B > C, threads A and B are in a suspended state, waiting for a certain event to occur, thread C is running, and task C starts to use the shared resource Source at this time. When using Source, thread A waits for the event to arrive, and thread A changes to the ready state. Because thread A has a higher priority than thread C, thread A will execute immediately. When thread A wants to use the shared resource Source, because the shared resource Source is being used by thread C, thread A is suspended and thread C starts running. If medium-priority thread B is waiting for an event to arrive at this time, thread B changes to the ready state. Since thread B has a higher priority than thread C, thread B starts running, and thread C does not start running until it finishes running. Thread A cannot be executed until thread C releases the shared resource Source. In this case, the priorities are flipped and thread B runs before thread A.

3. What are the consequences of priority inversion?

Low-priority tasks are executed before high-priority tasks, resulting in task confusion and logical confusion;

May cause system crash;

Deadlock; threads with low priority cannot be scheduled for a long time, and threads with high priority cannot be executed, resulting in deadlock;

4. How to avoid thread priority inversion

If the current thread is blocked due to waiting for an ongoing operation on a thread such as (block1), and the system knows the target thread where block1 is located, the system will solve the priority inversion problem by increasing the priority of the relevant thread (such as thread A During the period when the thread C is suspended while trying to obtain shared resources, the priority of thread C is raised to the priority of the same thread A, and when the processing of thread C is completed, it is lowered back to the original priority. This can prevent C from being preempted by B). If you don't know the target thread where block1 is located, you can't know whose priority should be increased, and you can't solve the problem of inversion, such as semaphores.

5. Using semaphores may cause thread priority reversal, which is unavoidable

QoS (Quality of Service), used to indicate the running priority of a task or queue;

1. APIs that record the holder can automatically avoid priority inversion. The system will solve the priority inversion problem by increasing the priority of the relevant thread, such as dispatch_sync. If the system does not know the thread where the holder is located, Then it is impossible to know whose priority should be increased, and the inversion problem cannot be solved.

2. Use dispatch_semaphore with caution for thread synchronization

dispatch_semaphore can easily cause priority inversion, because the API does not record which thread holds the semaphore, so when a high-priority thread is waiting for the lock, the kernel cannot know which thread's priority (QoS) to increase;

3. The reason why dispatch_semaphore cannot avoid priority inversion

When calling dispatch_semaphore_wait(), the system does not know which thread will call the dispatch_semaphore_signal() method. The system cannot know the owner information and cannot adjust the priority. dispatch_group is similar to semaphore. When calling the enter() method, it is impossible to predict who will leave(), so the system does not know the owner information.

References:

priority inversion

Priority inversion stuff

Diagnosing Performance issues early

dispatch_semaphore will cause priority inversion, use with caution!

Author: JD Retail Sun Qiaoqiao

Source: JD Cloud Developer Community Please indicate the source when reprinting

OpenAI opens ChatGPT Voice Vite 5 for free to all users. It is officially released . Operator's magic operation: disconnecting the network in the background, deactivating broadband accounts, forcing users to change optical modems. Microsoft open source Terminal Chat programmers tampered with ETC balances and embezzled more than 2.6 million yuan a year. Used by the father of Redis Pure C language code implements the Telegram Bot framework. If you are an open source project maintainer, how far can you endure this kind of reply? Microsoft Copilot Web AI will be officially launched on December 1, supporting Chinese OpenAI. Former CEO and President Sam Altman & Greg Brockman joined Microsoft. Broadcom announced the successful acquisition of VMware.
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/10150683