In daily development, we often use multithreading. Multithreading brings us great convenience and improves the execution efficiency of the program, but it also brings data race. The definition of data race is very simple: when at least two threads access the same variable at the same time, and at least one of them is a write operation, a data race occurs. Therefore, some synchronization mechanisms must be used to ensure the accuracy of the data. Locks are one of the synchronization mechanisms. How to detect Data race in a project? Just check Thread Sanitizer in the settings, and by the way, you can check Pause on issues to breakpoint to the corresponding code. Let's get down to business and talk briefly about locks in iOS and related content (due to my limited ability, there are inevitably some omissions or errors in the article, please feel free to give me your advice! Thank you!) Simple performance test The following figure is the result of my own test on the lock in iOS. The numbers in the figure represent the time required for each lock and unlock, in nanoseconds. The code is here, and the code is based on YY's no longer secure OSSpinLock, which is basically the same as YY's figure??, YY's unit is μs, which should be 1000 times, or maybe it's wrong~ LockPerformance.jpg Note: The running phone is: iPhone 6s plus, system version: 11.2.2, Xcode 9.2; the unit of the number is ns (the specific value obtained is the average of multiple runs). It is worth noting that: 1. This number only represents the time taken to unlock each time, and cannot fully represent the performance. 2. Different models and systems, different number of cycles may result in slightly different results. But it can still be seen that @synchronized: has the worst performance. Before we talk about these locks in detail, let's first talk about some conceptual definitions: (refer to Wikipedia)
Mutex 1.NSLock: It is a lock exposed to developers in the form of an object in the Foundation framework (the Foundation framework also provides NSConditionLock, NSRecursiveLock, and NSCondition).NSLock is defined as follows:
Both tryLock and lock methods request locks. The only difference is that trylock can continue to do some tasks and processing when the lock is not obtained. The lockBeforeDate method is also relatively simple, which is to obtain the lock before the limit time point, and return NO if it is not obtained. In the actual project: NSLock is used in AFURLSessionManager.m of AFNetworking as follows:
2.pthread_mutex: In actual projects: You can see this in YYMemoryCach of YYKit
3.@synchronized: In the actual project: getter method of isNetworkActivityOccurring attribute in AFNetworking
Spin lock 1.OSSpinLock:
The above is how to use OSSpinLock. The compiler will report a warning that it has been deprecated. OSSpinLock is no longer used because it is no longer safe in some scenarios. You can refer to YY master's no longer safe OSSpinLock. In the Protocol Buffers project, you can see such comments. Everyone has replaced it with a new solution.
2.os_unfair_lock: os_unfair_lock is the solution officially recommended by Apple to replace OSSpinLock, but it can only be called in systems above iOS10.0.
Read-write lock As mentioned above, the read-write lock is also called a shared-mutex lock. pthread_rwlock:
Recursive Lock A feature of recursive locks is that the same thread can be locked N times without causing deadlock. 1.NSRecursiveLock: NSRecursiveLock is used in YYWebImageOperation.m in YYKit:
2.pthread_mutex(recursive): The pthread_mutex lock also supports recursion, just set PTHREAD_MUTEX_RECURSIVE
Conditional Lock 1. NSCondition: definition:
Follow the NSLocking protocol. When used, it is also lock, unlock and unlock. Wait is to wait stupidly. The waitUntilDate: method is to wait for a while, which will block the thread. Signal is to wake up a waiting thread, and broadcast is to broadcast and wake up all.
2.NSConditionLock: definition:
It’s very simple, the method is very clear, and it’s basically the same as above. Semaphore dispatch_semaphore: dispatch_semaphore is used in YYThreadSafeArray.m in YYKit, and YY master has such a comment:
Summarize: In fact, this article is all about the most basic content. When reading some open source projects, you will often encounter some ways to keep threads synchronized. Because the selection may be different in different scenarios, this article will just make a simple record~ I believe that after reading this article, you should be able to choose the right lock according to different scenarios, and be able to tell the difference between spin locks and mutex locks. at last: Due to my limited ability, there are inevitably some omissions or errors in the article. Please feel free to give me your advice! Thank you! At the same time, if you have any questions about locks, you can leave a message, communicate together, and make progress together~?? I hope everyone can make a little progress every day~ |
<<: iOS 11–11.1.2 full jailbreak released: much better this time
In recent days, I believe everyone has been flood...
Leviathan Press: Cat owners know the flexibility ...
Artificial intelligence-related technologies inclu...
Recently, the Market Supervision and Administrati...
iQiyi has raised its prices again. From 0:00 on D...
When doing Baidu bidding, you must deal with mali...
Not long ago, #It is recommended that experts do ...
"When the ground is covered with mugwort and...
Last fall, the Securities and Exchange Commission...
The upcoming Lunar Year of the Tiger From Februar...
As the news of Alibaba's successful listing i...
As one of the control standards for many games, t...
On September 13, artificial intelligence company ...
Among the key communicators, in addition to the f...
It’s autumn now, and the happiest thing is to buy...