This article mainly explains from the following aspects, including: thread definition, process definition, the relationship between thread and process and the difference, the meaning of multi-threading, the principle of multi-threading, thread life cycle, the principle of thread pool, thread insecurity, thread communication, thread and runloop relationship.
1: thread definition
A thread is the basic execution unit of a process
All tasks of a process are executed in the thread.Main thread or child thread
{}
- In order for a process to perform a task, it must have threads, at least one thread
- By default, the program starts a thread, which is called the main thread or UI thread
2: Process definition
- Processes are in the system
A running application, active App
Each process is independent of each other, port
, each process runs in its own dedicated and protected memory
3. The relationship and difference between threads and processes
- Address space:
Threads of the same process share the address space of the same process, while processes are independent of each other
. - Resources owned:
Threads in the same process share the resources of the process, such as memory, I/O, CPU, etc., but the 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.
4. The meaning of multithreading
- advantages
- Can improve the execution efficiency of the program
- Increase resource utilization (CPU, memory)
The task on the thread is automatically destroyed after it completes execution
- disadvantages
- Starting a thread takes up some memory space (
By default, each thread is 512 KB. Technically, the child thread is 512 KB, the main thread is 1mb, and the main thread is 8mb on macos, so the memory is different on the real machine and emulator.
)
Developer.apple.com/library/arc…
- Starting a thread takes up some memory space (
- 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
The code can be found at github.com/tanghaitao/…
5. The principle of multithreading
The CPU continuously dispatches tasks between threads at a frequency called timeslice. When the timeslice is small enough, threading tasks are felt to be running simultaneously. That's how multithreading works
Multi-thread technical scheme
Single operation with GCD, customized encapsulation NSOperation.
[NSThread detachNewThreadSelector:@selector(threadTest) toTarget:self withObject:nil];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
});
pthread_t threadId = NULL;
char *str = "haitao";
pthread_create(threadId, NULL, pthreadDemo, str);
Copy the code
6. Thread lifecycle
For example, the specific code inGithub.com/tanghaitao/…
Number indicates that different threads have unique identifiers. The same name indicates that each thread has the same name.
A transaction that has been executed cannot be cancelled or suspended. A transaction can be cancelled or suspended only after the ongoing task is completed.
7. Principle of thread pool
Thread 2 is executed, it will call other threads, thread 3, for example, if the thread 2 without execution will determine whether the work queue is full, for example, one can only perform 2 times, there are two threads in the current queue, is full, and then determine whether the current queue of threads are in work, if is working state, saturated strategy, waiting in line, If there are idle threads in the full queue, a new thread is created to execute the task.
A simple example is a queue (bank window), with a maximum of four threads (window) and one VIP window at a time.
- Bank staff judge
Whether all 4 threads (Windows) are busy
- If they’re all full,
Query whether all Windows (including VIP Windows) are full
- If it’s full, then the bank clerk looks again
Whether all Windows are busy
, ‘the last person may have finished processing but there is no feedback to the work queue - If both are working, leave it to the saturation strategy (four strategies, no need to delve into).
Note: It is also possible that the thread pool work queue is full, and one of the threads is not in the working state, such as the last thread finished execution but did not report back to the work queue, which is equivalent to sleep
8. Threads are unsafe
Thread insecurity is mainly due to the problem of resource sharing by thread, such as simultaneous write operation, which will cause data inconsistency. The most typical problem is the train window ticket grabbing problem.
Specific code:Github.com/tanghaitao/…
Case studies of other locks: github.com/tanghaitao/…
Different lock characteristics, performance are explained in the project, here is not to say.
One more thing: the difference between noatomic and atomic
An atomic thread can read and write only one thread at a time. It is a spinlock. Suggestion: 1. All attributes should be declared as nonatomic. If the attributes are numeric, the default attribute atomic assign ReadWrite is atomic Strong readwirte. Avoid multiple threads grabbing the same resource. 3. Assign the service logic of locking and resource grabbing to the server to reduce the pressure on the mobile clientCopy the code
9 Thread Communication
Thread communication, generally speaking, is the communication between thread A and thread B, access data and other operations. For example, a child thread downloads an image and then dispatches to the main thread to update the UI through the thread pool.
[self performSelectorInBackground:@selector(downloadImageWithURL:) withObject:url];
[self performSelectorOnMainThread:@selector(updateImage:) withObject:image waitUntilDone:YES];
Copy the code
NSPort similar to valve, pipe communication address: github.com/tanghaitao/…
Added: Thread and runloop relationship
One runloop corresponds to a core thread. The reason why it is core is that runloops can be nested, but there can only be one core, and their relationship is stored in a global dictionary. 2: The runloop is used to manage threads. When the runloop is enabled, threads will go to sleep after completing tasks and will be woken up to execute tasks. 3: Runloop is created on the first fetch and destroyed at thread end. 4: For the main thread, the runloop is created by default as soon as the program starts. 5: 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.Copy the code