Processes and threads
1.1 process
A process is an application that is running in the system. Each process is independent of each other and runs in its own dedicated and protected memory.
1.2 the thread
A thread is the basic execution unit of a process. All tasks in a process are executed in a thread. Therefore, there must be at least one thread in a process. By default, iOS apps start a main thread, also known as the UI thread.
1.3 Relationship between processes and threads
- Address space: The address space in the same process can be shared by multiple threads in the same process, but the address space between processes is independent
- Resource ownership: Resources in the same process can be shared by all threads in the process, for example
memory
,I/O
,CUP
And so on, but resources between processes are independent of each other - The crash of any thread in a process can cause the entire process to crash, but the crash of a process does not affect another process
- A process can be seen as a container for threads. Each process has an entry point for the program to run, but threads cannot run independently and must depend on the process
1.4 the thread andRunloop
The relationship between
thread
withRunloop
It’s one to one, oneRunloop
Corresponds to aCore thread
Why is it core? BecauseRunloop
Can be nested, but there is only one core, and their correspondence is stored in a global dictionaryRunloop
It is used to manage threads. When they finish executing a task, they go to sleep and wake up when a task comes in and start executing it (event-driven).Runloop
It is created on the first fetch and destroyed at the end of the thread- The main thread of the
Runloop
It is created by default when the program starts - The child thread
Runloop
Is lazy-loaded and is created only when used, so used in child threadsNSTimer
Take care to ensure that the child threadRunloop
Created otherwiseNSTimer
It won’t go into effect.
1.5 Thread life cycle
The life cycle of a thread can be divided into five phases: new, ready, invoked, blocked, and dead.
multithreading
2.1 Concepts and Principles
A process can be concurrent with multiple threads to perform their respective tasks at the same time, called multithreading. Time-sharing operating system will reduce the CPU time length is divided into basic same time interval, the name is “time”, in a time slice, the CPU can only handle one thread of a task, for a single core CPU, in different time to perform the tasks in different threads, are formed multiple tasks at the same time perform “illusion” :
2.2 Multithreading commonly used in ios
In iOS, there are several ways to use multithreading:
1. Pthread: POSIX Thread, short for PThread, is the POSIX standard of threads. It is a set of universal multithreading API, which can be used cross-platform on Unix, Linux, and Windows platforms. It’s basically not used in iOS.
2.NSThread: An object-oriented thread class packaged by Apple, which can directly operate threads. Compared with GCD, NSThread is more efficient and is created by programmers themselves. Use frequency is low.
3.GCD: Grand Central Dispatch, realized by C language, is a solution proposed by Apple for multi-core parallel computing. CGD will automatically utilize more CPU cores and automatically manage the life cycle of threads. GCD is also the most used multi-threading technology on iOS.
4.NSOperation: Object-oriented multithreading technology encapsulated based on GCD, often used with NSOperationQueue, high frequency of use.
The thread pool
Thread Pool
A pool that manages the life cycle of multiple threads. There is no direct contact with thread pools in iOS development, because GCD already includes management of thread pools, and we just need threads from GCD to perform tasks.The life cycle of a thread
The life cycle of a thread includescreate
—ready
—run
—death
With these four phases, we can control the life cycle of the thread by blocking, exiting, and so on.
Communication between threads
4.1 Communication modes between several threads
Direct messaging
: This is very familiar –performSelector
: series.Global variables...
: Direct passageglobal
Variables,The Shared memory
And so on, but this way will cause resource grab, involving thread safety issues.The Conditions:
A special type of lock, the conditional lock, is used to make a thread wait, and the thread blocks and goes to sleep. When a single is sent to the same conditional lock in another thread, the waiting thread is awakened to continue executing the task.Run loop sources
: CustomizeRun loop sources
This will be studied separately in a later articleRun loop
.Ports and sockets
: Implements thread communication through ports and sockets.
4.2 Example of communication between threads
- First create the port in the main thread, set up the proxy, and then add the port to the Runloop to start the child thread.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Port thread communication"; self.view.backgroundColor = [UIColor whiteColor]; Self. MyPort = [NSMachPort]; self. MyPort = [NSMachPort]; Self.myport.delegate = self; self.myport.delegate = self; [[NSRunLoop currentRunLoop] addPort:self.myPortforMode:NSDefaultRunLoopMode];
self.person = [[KCPerson alloc] init];
[NSThread detachNewThreadSelector:@selector(personLaunchThreadWithPort:)
toTarget:self.person
withObject:self.myPort];
}
Copy the code
- Here, the child thread sends a message to the main thread through Port.
- (void)personLaunchThreadWithPort:(NSPort *)port{
NSLog(@"VC responds to Person"); Autoreleasepool {//1. Save the mainline port self.vcPort = port; //2. Set the name of the child thread [[NSThread currentThread]setName:@"KCPersonThread"]; Runloop [[NSRunLoop currentRunLoop] run]; // create self port self.myPort = [NSMachPort port]; Self.myport.delegate = self; self.myport.delegate = self; //6. Finish sending the message to the main thread port [self sendPortMessage]; }} /** * sendPortMessage {NSData *data1 = [@"Gavin" dataUsingEncoding:NSUTF8StringEncoding];
NSData *data2 = [@"Cooci"dataUsingEncoding:NSUTF8StringEncoding]; NSMutableArray *array =[[NSMutableArray alloc]initWithArray:@[data1,self.myPort]]; // Send a message to the main thread of the VC // first argument: send time. // msgid message id. // components, send messages with parameters. / / reserved: Number of bytes reserved for the header [self.vcPort sendBeforeDate:[NSDate Date] MSgid :10086 Components :array from: self.myport reserved:0]; }Copy the code
- The main thread takes the data and sends a message to the child thread.
- (void)handlePortMessage:(NSPortMessage *)message{
NSLog(@"VC == %@",[NSThread currentThread]);
NSLog(@"Pass some information from person :");
// NSLog(@"localPort == %@",[message valueForKey:@"localPort"]);
// NSLog(@"remotePort == %@",[message valueForKey:@"remotePort"]);
// NSLog(@"receivePort == %@",[message valueForKey:@"receivePort"]);
// NSLog(@"sendPort == %@",[message valueForKey:@"sendPort"]);
// NSLog(@"msgid == %@",[message valueForKey:@"msgid"]);
// NSLog(@"components == %@",[message valueForKey:@"components"]); //NSLog(@) does not have this hidden attribute"from == %@",[message valueForKey:@"from"]);
NSArray *messageArr = [message valueForKey:@"components"];
NSString *dataStr = [[NSString alloc] initWithData:messageArr.firstObject encoding:NSUTF8StringEncoding];
NSLog(@"Pass some information :%@",dataStr);
NSPort *destinPort = [message valueForKey:@"remotePort"];
if(! destinPort || ! [destinPort isKindOfClass:[NSPort class]]){ NSLog(@"The data sent was wrong.");
return;
}
NSData *data = [@"VC received!!!!!!"dataUsingEncoding:NSUTF8StringEncoding]; NSMutableArray *array =[[NSMutableArray alloc]initWithArray:@[data,self.myPort]]; // Very important, if you want to receive information in Person's port, you must add runloop [[NSRunLoop currentRunLoop] addPort:destinPort to the current main threadforMode:NSDefaultRunLoopMode];
NSLog(@"VC == %@",[NSThread currentThread]);
BOOL success = [destinPort sendBeforeDate:[NSDate date]
msgid:10010
components:array
from:self.myPort
reserved:0];
NSLog(@"%d",success);
}
Copy the code
- The child thread receives the message sent by the main thread
- (void)handlePortMessage:(NSPortMessage *)message{
NSLog(@"person:handlePortMessage == %@",[NSThread currentThread]);
NSLog(@"Some information from VC :");
NSLog(@"components == %@",[message valueForKey:@"components"]);
NSLog(@"receivePort == %@",[message valueForKey:@"receivePort"]);
NSLog(@"sendPort == %@",[message valueForKey:@"sendPort"]);
NSLog(@"msgid == %@",[message valueForKey:@"msgid"]);
}
Copy the code
At this point, the example of communication between threads via port is complete.