The path of the architect ~ fundamental principle 4 :(performance optimization, architecture)

Xiv. Multithreading

14.1 ios Multithreading Scheme

pthread / NSThread /GCD /NSOperation
Copy the code

14.2 Common functions of GCD

GCD has two functions that execute tasks dispatch_sync(dispatch_queue_t queue, dispatch_block_t block). Queue: queue block: tasks are performed asynchronously dispatch_async(dispatch_queue_t queue, dispatch_block_t block). The GCD source: https://github.com/apple/swift-corelibs-libdispatchCopy the code

14.3 GCD Queue

GCD queues can be divided into two types of Concurrent Dispatch queues, which allow multiple tasks to execute concurrently (automatically enable multiple threads to execute tasks simultaneously). The concurrency function is only available under the asynchronous (dispatch_async) function Serial Dispatch queues allow tasks to be executed one after another (after one task is completed, the next task is executed)Copy the code

14.4 Confusing terms

There are four terms compare easily confused: synchronous and asynchronous serial synchronous and asynchronous, concurrent, main effect: can open a new thread synchronization: perform a task in the current thread, do not have the ability to open a new thread Asynchronous: on a mission in the new thread, have the ability to open a new thread Concurrent and serial main effect: the task execution Concurrent: Concurrent execution of multiple tasks Serial: After one task is executed, the next task is executedCopy the code

14.5 Execution Effects of Queues

14.6 GCD Queue Group Usage

14.7 Multi-threading Security Risks

Resource sharing A resource may be shared by multiple threads, that is, multiple threads may access the same resource. For example, multiple threads may access the same object, variable, or file. When multiple threads access the same resource, data corruption and data security problems may occurCopy the code

14.8 Solution to Multi-threading Security Risks

14.9 Thread Synchronization Scheme in iOS Thread safety. Thread lock

Solution: Use thread synchronization (synchronization, which is synchronized, in a predetermined order) common thread synchronization technique: locking

OSSpinLock
os_unfair_lock
pthread_mutex
dispatch_semaphore
dispatch_queue(DISPATCH_QUEUE_SERIAL)
NSLock
NSRecursiveLock
NSCondition
NSConditionLock
@synchronized

Copy the code

14.10 OSSpinLock Is Unsafe

14.11 OSUnfairLock (mutex) Is the most efficient

14.12 the pthread_mutex

The mutex is a mutex, and the thread waiting for the lock will sleep

14.13 NSLock, NSRecursiveLock

14.14 NSCondition

14.15 dispatch_queue (SerialQueue)

Use GCD serial queue to achieve synchronizationCopy the code

14.16 Dispatch_semaphore can be used to control the maximum number of concurrent requests

Semaphore The initial value of a semaphore that can be used to control the maximum number of concurrent accesses by a thread. The initial value of a semaphore is 1, indicating that only one thread is allowed to access the resource at a time, ensuring that the threads are synchronizedCopy the code

14.17@synchronized

Objc4 objC-sync. mm file @synchronized(obj) will generate the corresponding recursive lock obJ, and then lock, unlock the operationCopy the code

14.18 Performance Comparison of iOS Thread Synchronization Schemes

Os_unfair_lock ios10 Start OSSpanLock ios10 Disuse dispatch_semaphore dispatch_mutex dispatch_queue Serial NSLock indicates mutex encapsulation @ synchronized worstCopy the code

14.19 Comparison between Spin Locks and Mutex

When is it cost-effective to use a spin lock? Threads are expected to wait very short for locks Locking code is called frequently, but contention is rare CPU resources are not tight multi-core processors when is it cost-effective to use mutex? It is expected that the thread will wait for a long time to lock. In the critical area of a single-core processor, IO operations exist. In the critical area, the code is complex or the number of cycles is largeCopy the code

14.20 Atomic and Noatomic

Atomic is used to guarantee atomicity of property setters and getters. It is equivalent to locking thread synchronization inside getters and setters. See objC-accessors.mm of objC4Copy the code

14.21 Multithreading Read-write Thread Security Solution

Consider how to implement the following scenario: Only one thread can perform write operations at a time. Multiple threads are allowed to perform read operations at the same time. Both write and write operations are not allowed at the same time. In iOS, pthread_rwlock: read/write lock dispatch_barrier_async: asynchronous fence callCopy the code

14.22 pthread_rwlock

14.23 dispatch_barrier_async

15. Memory management

15.1 Usage of CADisplayLink and NSTimer

CADisplayLink ensures that the call frequency and brush frame frequency are always 60FPS, without setting the time interval,60 times per second. CADisplayLink can be used as a proxy to resolve the circular reference. If target makes strong references to them again, circular references are raisedCopy the code

Solution 1. Use blocks

Solution 2. Use proxy objects (NSProxy)

15.2 NSProxy also belongs to the base class

Proxy, used to solve circular references, used for message forwarding, does not look up methods NSObject in the parent class differently from NSProxyCopy the code

15.3 GCD Timer

NSTimer relies on RunLoop. If RunLoop is too busy, NSTimer may not be on time, whereas GCD timers are more punctual. GCD timers, independent of RunLoop, are punctual and kernel dependentCopy the code

15.4 Memory Layout of iOS Applications

Low address -> High address reservation -> Code segment -> Data segment (string constant, initialized global data, uninitialized data)> heap -> stack memory -> Kernel area code segment: compiled code segment: String constants, initialized global variables, or static variables, uninitialized global variables, static variable heap (low > high) dynamically allocated memory stack by alloc malloc calloc (high address from low address) Function call overhead ()Copy the code

15.5 Tagged Pointer

Starting from 64bit, iOS introduces Tagged Pointer technology to optimize storage of small objects such as NSNumber, NSDate, and NSString. Before using Tagged Pointer, objects such as NSNumber need to dynamically allocate memory and maintain reference counting. The NSNumber Pointer stores the address value of the NSNumber object in the heap. After using Tagged Pointer, the data stored in the NSNumber Pointer becomes: The objc_msgSend method can recognize Tagged Pointer. For example, the intValue method of NSNumber extracts Data directly from the Pointer. How to determine if a Pointer is Tagged Pointer? For iOS, the highest significant bit is 1 (64bit). For Mac, the lowest significant bit is 1Copy the code

Check whether the state is Tagged Pointer

15.6 Memory Management of OC Objects

A newly created OC object's reference count defaults to 1. When the reference count is reduced to 0, the OC object is destroyed, freeing up its memory. A call to retain gives the OC object's reference count +1. So when you call the alloc, new, copy, mutableCopy methods and you return an object, when you don't need that object, you call release or autoRelease and you want to own that object, Let its reference count be +1; Extern void _objc_autoreleasePoolPrint(void) extern void _objc_autoreleasePoolPrint(void);Copy the code

15.7 copy and mutableCopy

15.8 Store retainCount for reference counters

15.9 dealloc

15.10 autoreleasePool Automatically releases the pool

The main underlying data structures for auto-release pools are: __AtAutoreleasePool, AutoreleasePoolPage calls autorelease objects are ultimately managed by the AutoreleasePoolPage object -objC4 source: nsobject.mmCopy the code

15.11 Structure of AutoreleasePoolPage

The push method will push a POOL_BOUNDARY onto the stack and return its memory address. The pop method will pass in a POOL_BOUNDARY memory address and send a release message starting from the last object pushed. Until the POOL_BOUNDARY ID *next points to the next area that can hold the address of the AutoRelease objectCopy the code

15.12 runloop and autoreleasePool

IOS registers two observers in the main thread Runloop - the first Observer listens for the kCFRunLoopEntry event, Objc_autoreleasePoolPush () - the second Observer listens for the kCFRunLoopBeforeWaiting event, Objc_autoreleasePoolPop () will be called. Objc_autoreleasePoolPop () will be called if it listens for kCFRunLoopBeforeExit.Copy the code

Reference: iOS Basic Principles class (part 2) /OC object/Associated object/multi-threading/memory management/performance optimization