In peacetime development, multithreading is also closely related to our development and is widely used, this chapter on the study of multithreading to make a record.

One: base-thread process queue

1.1 What is a process

  • processIt refers to an application that is running in the system. Any App on the phone is a process.
  • eachprocessIt’s independent of each otherprocessBoth run on dedicated and protected memory, and the crash of one process does not affect other processes.
  • You can view it through the Activity MonitorMacThe process that is started in the system.

1.2 What is a thread

  • A thread is the basic execution unit of a process, in which all tasks of a process are executed.
  • processIn order to carry out a mission, you have to havethread.processHave at least onethread.
  • Program startup will open one by defaultthread, this articlethreadKnown asThe main threadorThe UI thread.

1.3 Differences between processes and threads

  • Address space: Threads of the same process share the address space of the same process, while processes are independent of each other.
  • Resource ownership: Threads in the same process share the resources of the same process, such as memory, I/O, and CPU, but resources between processes are independent.
  • The crash of one process in protected mode does not affect other processes, but the crash of one thread kills the entire process. So multi-processing is more robust than multi-threading.
  • Process switchover consumes large resources and is efficient. So when it comes to frequent switching, threads are better than processes. Also, if you require concurrent operations that share variables at the same time, use threads instead of processes.
  • Execution process: Each independent process has a program run entry, sequential execution sequence, and program entry. However, threads cannot execute independently and must depend on the application, which provides multiple thread execution control.
  • Threads are the basic unit of processor scheduling, but processes are not.
  • Threads have no address space and are contained in the process address space.

1.4 Threads and Runloops

  • Runloops correspond to threads one by one. A runloop corresponds to a core thread, which is core because runloops can be nested, but there can only be one core, and their relationship is stored in a global dictionary.

  • Runloop is used to manage threads. When a thread’s Runloop is enabled, the thread will go to sleep after executing a task. When a task is available, the thread will be awakened to perform the task.

  • The runloop is created on the first fetch and destroyed at the end of the thread.

  • For the main thread, the runloop is created by default as soon as the program starts.

  • For child threads, runloops are lazily loaded and only created when we use them, so be careful when using timers on child threads: make sure the runloop is created for the child thread, otherwise the timer will not call back.

Two: multi-threading

2.1 Significance of Multi-threading

advantages

  • Can improve the execution efficiency of the program.
  • Can appropriately improve the utilization of resources (CPU, memory).
  • The task on the thread is automatically destroyed after it completes execution.

disadvantages

  • Starting threads takes up a certain amount of memory (512 KB per thread by default).
  • If a large number of threads are enabled, a large amount of memory space will be occupied and the performance of the program will be reduced.
  • The more threads there are, the more overhead the CPU has on calling threads.
  • The program design is more complex, such as communication between threads, multithreaded data sharing.

2.2 Principle of Multi-threading

The concept of time slice: the CPU performs a fast switch between multiple tasks directly, and this time interval is the time slice

  • (A single core CPU) At the same time,CPUOnly one thread can be processed, in other words, only one thread is executing at a time
  • Multithreading at the same time isCPUFast switching between multiple threads,CPUScheduling threads fast enough creates multithreadingAt the same timeThe effect of execution. But if the number of threads is very large,CPUWill be inNSwitching between threads consumes a lot ofCPUResources, each thread is scheduled less times, thread execution efficiency is reduced.

2.3 Thread life cycle

  • New: Instantiate the thread object

  • Ready: A start message is sent to the thread object, which is added to the pool of schedulable threads waiting for CPU scheduling.

  • Run: The CPU is responsible for scheduling the execution of threads in the schedulable thread pool. Before the thread completes execution, the state may switch back and forth between ready and run. State changes between ready and run are the responsibility of the CPU, not the programmer.

  • Blocking: When a predetermined condition is met, sleep or locking can be used to block thread execution. SleepForTimeInterval, sleepUntilDate, @synchronized(self) :(mutexes).

  • Death: Normal death, thread execution completed. Unnatural death, aborting execution inside a thread/aborting a thread object in the main thread when a condition is met.

The thread pool

Thread pool (English: Thread pool) : a thread usage pattern. Too many lines will bring scheduling overhead, which will affect cache locality and overall performance. A thread pool maintains multiple threads, waiting for the supervisor to assign tasks that can be executed concurrently. This avoids the cost of creating and destroying threads while working on short-duration tasks.

  • If both are in the execution state, theSaturation strategy processing.
  • If full, it determines whether the threads are all executing, and if not, it assigns non-core threads to execute
  • If both are executing, the work queue is checked to see if it is full, and if it is not, the task is stored on the work queue
  • When a new task comes in, it checks whether the thread pool is all executing the task, ifA thread is created to execute the task if it does not arrive

There are four modes of saturation strategy:

  1. DisCardPolicy: Directly discards the task
  2. DisOldestPolicy: Drop the most waiting task
  3. CallerRunsPolicy: rolls back the task to the caller
  4. AbortPolicy: Direct throwRejectedExecutionExeceptionException to prevent the normal operation of the system

2.4 Multi-threading Scheme

Technical solution Introduction to the language Thread life cycle Using a review of the rate
pthread A set of universal multithreading API, suitable for Unix/Linux/Windows systems, cross-platform/portable, difficult to use C Programmer management Almost no
NSThread Use more object-oriented, easy to use, direct manipulation of thread objects OC Programmer management Occasionally use
GCD Designed to replace threading technologies such as NSThreads and take full advantage of the device’s multi-core C Automatic management Often use
NSOperation Based on GCD (bottom is GCD), more simple and practical functions than GCD, use more object-oriented OC Automatic management Often use

2.5 Communication between threads

  • Direct messaging: Through a series of performSelector methods, it is possible to execute a task on another thread specified by one thread. Since the execution context of the task is the target thread, messages sent in this manner will be automatically serialized

  • Global variables, shared memory blocks, and objects: Another simple way to pass information between two threads is to use global variables, shared objects, or shared memory blocks. Although shared variables are fast and easy, they are more fragile than direct messaging. Shared variables must be carefully protected using locks or other synchronization mechanisms to ensure correct code. Failure to do so may result in competitive conditions, data corruption, or crashes.

  • Conditional execution: A condition is a synchronization tool that can be used to control when a thread executes a particular part of code. You can treat a condition as a lock and let the thread run only when the specified condition is met.

  • Runloop Sources: A custom Runloop source configuration allows specific application messages to be received on a thread. Because Runloop sources are event-driven, threads automatically go to sleep when there is nothing to do, increasing thread efficiency

  • Ports and Sockets: Port-based communication is a more sophisticated way to communicate between two threads, but it’s also a very reliable technique. More importantly, ports and sockets can be used to communicate with external entities, such as other processes and services. To improve efficiency, the port is implemented using a Runloop source, so the thread goes to sleep when there is no data waiting on the port

  • Message queues: Traditional multiprocessing services define a first-in, first-out (FIFO) queue abstraction for managing incoming and outgoing data. Although message queues are simple and convenient, they are not as efficient as some other communication technologies

  • Cocoa Distributed Objects: Distributed objects are a Cocoa technology that provides a high-level implementation of port-based communication. Although it is possible to use this technique for interthread communication, it is strongly recommended not to do so because of the overhead involved. Distributed objects are better suited for communicating with other processes, although transactions between these processes are also expensive

2.6 Thread Safety

In the use of multithreading, there is often a resource grab problem, then it is necessary to use thread synchronization technology to solve the problem of thread safety, the so-called thread synchronization: that is, when one thread access data is not finished, other threads can not access the same data.

Thread synchronization technology solutions are many, one of them is the lock, you can see this article is no longer safe OSSpinLock

Thread safety will be covered in more detail in later chapters, but will not be covered here.

Here’s an extension onatomic and nonatomic: atomic

  • Is the atomic property, is for multithreaded development, is the default property!
  • Only in attributessetterMethod, adding a lock (spin lock) to ensure that only one thread works on a property at a timewriteoperation
  • A thread-processing technique in which one (thread) writes more than one (thread) reads at a time

nonatomic 

  • Nonatomic property
  • There is no lock! High performance!

Reference: Multithreading series