Threads and processes

thread

  • threadIs a process ofBasic execution unit, a processEverything executes in the thread
  • In order for a process to perform a task, it must have threads,A process must have at least one thread
  • The program starts with a thread by default, this thread is calledThe main threadorThe UI thread

process

  • processRefers to theAn application that is running on the system
  • eachProcesses are independent from each otherEach process runs in its own dedicated and protected memory space
  • The Activity Monitor allows you to view the threads that are started in the MAC system

Processes are containers for threads, and threads are used to perform tasks. In iOS, it is a single process development, a process is an APP, the process is independent of each other, such as Alipay, wechat, QQ, etc., these are different processes

The relationship between processes and threads

  • Thread is attached to the process, can not exist independently, it is contained in the process, is the actual operation unit in the process. Once a process terminates, all threads terminate.
  • A thread can only belong to one process, and a process can have multiple threads, but at least one thread.

There are two main aspects to the relationship between processes and threads

A thread is a unit of execution in a process, scheduled independently by the CPU, responsible for the execution of tasks in the current process. A process can have one or more threads. Multiple threads in the same process will share the memory space of the program, that is, the code segment (code and constant), data segment (global and static variables), extended segment (heap storage) and other system resources in the process.

The difference between processes and threads

  • Fundamental difference

    A process is the smallest unit of resources allocated by the operating system, and a thread is the smallest unit of program execution

  • Address space

    • Of the same processThreads share the address space of the process
    • whileProcesses are separate address Spaces
  • Resources have

    • Within the same processThreads share resources of the process, such as memory, I/O, CPU, etc
    • butResources are independent between processes

The relationship between the two is equivalent to that between the factory and the assembly line, which are mutually independent, while the assembly line in the factory shares the resources of the factory, that is, the process is equivalent to a factory, and the thread is equivalent to an assembly line in the factory

  • Multiple processes are more robust than multiple threads

    • A process crash in protected mode does not affect other processes
    • whileOne thread crashes and the entire process dies
  • Scheduling and switching

    • Process switchover consumes large resources and is efficient. So it comes down toFrequent switchingWhen,Threads are better than processes.
    • If the samerequirementsSimultaneous and sharing of variablesThe concurrent operation.Thread onlyUnable to use process
  • Implementation process

    • Each individualprocessThere is a programRunning entryOrder,Execution sequenceandProgram entrance
    • butThreads cannot execute independently and must depend on the applicationThe application provides multiple threads of execution control.

Thread and Runloop relationship

  • Runloops correspond to threads one by oneA runloop corresponds to a core threadRunloops can be nested, but there can only be one coreTheir relationship is stored in a global dictionary.
  • Runloop is used to manage threads, when the thread runloop is enabled, the thread will go to sleep after completing the task and will be woken up to execute the task.
  • The runloop is created on the first fetch and destroyed at the end of the thread.
  • forThe main threadSpeaking,Runloop is created by default as soon as the program startsAll right.
  • forThe child threadSpeaking,Runloop is lazily loadedIt’s only created when we’re using it, soUse timers on child threadsPay attention toMake sure the runloop for the child thread is created, otherwise the timer will not call back.

Multi-process vs. multi-thread

Multitasking can be implemented by multiple processes, multiple threads within a single process, or a combination of multiple processes and multiple threads. Hybrid multi-process and multi-threaded programs involve synchronization and data sharing issues, which are more complex and rarely used in practice.

The advantages of multi-threading over multi-process are:

  • The threadScheduling and switchingThan processfastA lot, and the overhead of creating a thread is much lower than that of a process;
  • interthreadEasier communication, threads under the same process share global variables, static variables and other data, inter-thread communication is to read and write the same variable, fast. Communication between processes needs to be carried out in the form of Inter Process Communication (IPC).

The advantages of multiple processes are:

  • Multiprocess programMore robustIn the case of multiple processes, the crash of one process does not affect other processes, while in the case of multiple threads, the crash of any one thread directly causes the crash of the entire process.

multithreading

How does a single-core CPU multitask?

Time slice rotation scheduling: To put it simply, a processor is divided into several short time slices. Each process is allocated a time slice by the operating system (that is, the time it takes for the CPU to execute the current process). Each time slice in turn executes and processes each application program. The operating system forces the CPU resource to be executed by another process because a time slice is too short to achieve the effect of multiple applications running at the same time.

Principle of multithreading

  • forA single core CPU.The CPU can only process one thread at a timeThat is, only one thread is working,
  • In the iOSMultithreading simultaneous executionIs the nature ofThe CPU switches between multiple tasks directly and quicklyBecause ofCPU scheduling threadtheTime is fast enoughIs caused byMulti-threaded "simultaneous" executionThe effect. Where the switching interval isTime slice

Meaning of multithreading

  • Can improve the execution efficiency of the program

  • Improves resource utilization, such as CPU and memory

  • The task on the thread is automatically destroyed after it completes execution

  • Starting threads requires a certain amount of memory. By default, each thread occupies 512KB

  • If a large number of threads are enabled, a large amount of memory space will be occupied, reducing the performance of the program

  • The more threads there are, the more overhead the CPU has on calling threads

  • Programming is more complex, such as communication between threads, data sharing between multiple threads

Multithreaded life cycle

The life cycle of multithreading is divided into five parts: new – ready – run – block – death, as shown in the following figure

Multithreaded declaration cycle

  • new(new)

The Thread object is instantiated, and memory is allocated to the Thread after it is created. When a thread is in the “new thread” state, it is just an empty thread object that has not yet been allocated system resources. So you can only start() or stop() it. Any other operation throws an exception.

  • Ready (Runnable)

The thread object calls the start() method, adds the thread object to the schedulable thread pool, and waits for the CALL of the CPU. In other words, the start method is called, but it will not be executed immediately and will enter the ready state. It needs to wait for a period of time before running () is executed after the CPU schedules it, that is, from the ready state to the running state

  • Run (Running)

A thread in the ready state does not have to run the run() method immediately, it must also compete with other threads for CPU time, and it can only run if it obtains CPU time

  • Obstruction (Blocked)

    You can use hibernation when certain predetermined conditions are met, namely sleep, suspend(),IO blocking, wait() for notification, wait for a synchronization lock, and block thread execution.

    The following Settings for sleep time are for NSThreads

    • sleepUntilDate:Blocks the current thread until the specified time, i.eSleep until a specified time
    • sleepForTimeInterval:Hibernates a thread for a given time interval, i.eSpecify sleep duration
    • Synchronization locks:@ synchronized (self) :

When the stop() time reaches, resume(), the IO block returns, the notification is received, the synchronization lock is acquired, etc., and the thread moves from the blocked state to the ready state, waiting for the CPU to schedule.

  • Death (Dead)

    • Normal deathThat is, the thread completes execution
    • Unnatural deathWhen a condition is met, execution terminates inside the thread (or in the main thread) (exit calls,stop methods, etc.) or an Error or Exception occurs

conclusion

A running thread has a period of time (called a timeslice) that it can execute.

  • ifTime slice exhausted, the thread will enterReady state queue
  • ifThe time slot is not used upAnd you need to startWait for something, will enterBlocking status queue
  • After an event occurs, the thread will re-enterReady state queue
  • Whenever aThread out of run, that is, after the execution is complete or forced to exit, the system will retryFrom the ready state queueIn theSelect a thread to continue execution

Exit and cancel instructions for the thread

  • exit: Once the thread is forcibly terminated, all subsequent code is not executed
  • cancel: Cancels the current thread, but not the executing thread

The higher the priority of the thread, the faster the task will be executed?

No, the speed of thread execution depends not only on priority, but also on resource size (i.e. task complexity) and CPU scheduling. In nsthreads, threadPriority has been replaced by qualityOfService, as enumerated below

Thread Pool Principle

Thread Pool Principle

  • [Step 1] Determine whether the core thread pool is all executing tasks

    • Return NO and create a new worker thread to execute
    • Return YES to enter [Step 2]
  • [Step 2] Determine whether the thread pool work queue is full

    • Returns NO and stores the task to a work queue waiting for CPU scheduling
    • Return YES to enter [Step 3]
  • 【 Step 3 】 Check whether all threads in the thread pool are in the executing state

    • Returns NO to schedule free threads from the schedulable thread pool to execute the task
    • Return YES to enter [Step 4]
  • [Step 4] Give saturation strategies to execute, mainly including the following four strategies (the following four strategies are not found in iOS)

    • AbortPolicy: direct selling RejectedExecutionExeception exceptions to prevent normal operation of system
    • CallerRunsPolicy: rolls back the task to the caller
    • DisOldestPolicy: Drop the most waiting task
    • DisCardPolicy: Directly discards the task

IOS multithreading implementation scheme

There are four ways to implement multithreading in iOS: pThread, NSThread, GCD, and NSOperation, as shown in the figure

//pthread
pthread_t threadId = NULL;
/ / c string
char *cString = "HelloCode";
Pthread_t: pointer to the structure of the thread to be created. Normally, if you encounter C structures, the type suffix '_t/Ref' does not need to end with '*' 2. Thread property, nil(NULL object -oc used)/NULL(NULL address, 0 C used) 3. Void *: returns a pointer to any object similar to the id in OC (*): returns a pointer to any object similar to the id in OC (*): returns a pointer to any object similar to the id in OC (*) The argument */ passed to the third argument (function)
int result = pthread_create(&threadId, NULL, pthreadTest, cString);
if (result == 0) {
    NSLog(@ "success");
} else {
    NSLog(@ "failure");
}
    
//NSThread
[NSThread detachNewThreadSelector:@selector(threadTest) toTarget:self withObject:nil];
    
//GCD
dispatch_async(dispatch_get_global_queue(0.0) ^ {[self threadTest];
});
    
//NSOperation
[[[NSOperationQueue alloc] init] addOperationWithBlock:^{
    [self threadTest];
}];

- (void)threadTest{
    NSLog(@"begin");
    NSInteger count = 1000 * 100;
    for (NSInteger i = 0; i < count; i++) {
        / / the stack area
        NSInteger num = i;
        / / constant area
        NSString *name = @"zhang";
        / / heap area
        NSString *myName = [NSString stringWithFormat:@"%@ - %zd", name, num];
        NSLog(@ "% @", myName);
    }
    NSLog(@"over");
}

void *pthreadTest(void *para){
    // A string in the C language
    // NSLog(@"===> %@ %s", [NSThread currentThread], para);
    // __bridge Bridges C types to OC types
    NSString *name = (__bridge NSString *)(para);
    
    NSLog(@ "= = = > % @ % @"[NSThread currentThread], name);
    
    return NULL;
}
Copy the code

Bridge between C and OC

  • __bridgeI only do type conversions, butDo not modify object (memory) management rights
  • __bridge_retained(Also availableCFBridgingRetain) will beThe object of Objective - CconvertCore Foundation object, while putting the object (memory)The management is in our hands, the subsequentYou need to use CFRelease or related methods to release objects
  • __bridge_transfer(Also availableCFBridgingRelease) will beCore FoundationObject conversion ofIs an Objective-C objectAnd at the same time willObject (memory) management is given to ARC.