Introduction to Multithreading principle and Runloop in iOS

Source: Internet
Author: User

Original: http://geeklu.com/2012/02/thread/

I. Threading Overview

Some programs are a straight line, starting point to the end point; some programs are a circle that keeps looping until it is cut off. A straight line, such as the simple Hello World, runs out of print, its life cycle is over, like a flash in the pan, a circle like an operating system that runs until you turn it off.
A running program is a process or a task, a process contains at least one thread, and the thread is the execution flow of the program. The program in Mac and iOS starts, and while the good one process is created, a thread starts running, which is called the main thread. The main thread's position in the program is different from other threads, and it is the final parent thread of the other thread, and the operation of all interface display operations i.e. AppKit or uikit must be done on the main thread.
Each process in the system has its own independent virtual memory space, while multiple threads in the same process share the process's memory space. Each time a new thread is created, it requires some memory (for example, each thread has its own stack space) and consumes a certain amount of CPU. In addition, when multiple threads compete for the same resource, you need to be aware of thread safety issues.

Two. Create a thread

To create a new thread is to add an execution stream to the process, and the execution flow must have code to execute, so a new thread needs to provide a function or method as a thread's entry.

1. Using Nsthread

Nsthread provides a way to create threads, and also provides a way to detect whether the current thread is the main path. There are two ways to create a new thread using Nsthread:

    • 1. Create an Nsthread object and call its Start method. For the creation of a Nsthread object in this way, you can initialize a Nsthread object with a method of the target object, or create a subclass of the inheriting Nsthread class, implement its main method, and then create the object of the subclass directly.
    • 2. Use detachNewThreadSelector:toTarget:withObject: This class method to create a thread, which is more straightforward, using the target object's method as a thread to start the portal.
2. Using NSObject

In fact, NSObject directly joined the multi-threaded support, allowing a method of the object to run in the background. Such as:

[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];
//只是将任务的模式降低到kCFRunLoopCommonModes;仍然是在当前线程中处理(Main Thread)
3.POSIX Thread

Since both Mac and iOS are based on the Darwin system, the Xun kernel of the Darwin system, which is based on Mach and BSD, inherits the BSD POSIX interface, so you can use the thread directly with the relevant interface of the POSIX thread.

The interface for creating a thread is pthread_create , of course, the properties of the thread can be set by the correlation function before it is created. The following is a simple example of using POSIX threads.

//Main.cPthread#include <stdio.h>#include <pthread.h>#include <unistd.h>void*Pthreadroutine(void*);IntMain(Intargc,ConstChar*Argv[]){pthread_attr_tattr;pthread_tPthreadid;IntReturnVal;ReturnVal=Pthread_attr_init(&attr);ReturnVal=Pthread_attr_setdetachstate(&attr,Pthread_create_detached);IntThreaderror=Pthread_create(&Pthreadid,&attr,&Pthreadroutine,Null);ReturnVal=Pthread_attr_destroy(&attr);If(Threaderror!=0){Report an error.}Sleep(10);Return0;}void *pthreadroutine ( void *data) {int count = 0while  (1) { Printf ( "count =%d\n"  count++); sleep (1} return null;}      
Three. Multithreading Advanced Nsoperation&nsoperationqueue

Many times we use multi-threading, we need to control the number of concurrent threads, after all, the thread also consumes the system resources, when the program runs too many threads, the system must be slow. So many times we control the number of threads running concurrently.

Nsoperation can encapsulate our operations and then put the created Nsoperation object into Nsoperationqueue, and Operationqueue starts to start a new thread to perform the operations in the queue. The concurrency of Operationqueue can be set in the following ways:

- (void)setMaxConcurrentOperationCount:(NSInteger)count
GCD

GCD is the acronym for Grand Central Dispatch, a series of BSD-level interfaces that were introduced after Mac 10.6 and iOS4.0, and now the implementation of multithreading in Nsoperation and Nsoperationqueue is based on GCD. This feature has also been ported to FreeBSD and can be viewed in the Libdispatch open source project.

For example, a larger picture is displayed in a uiimageview.

dispatch_queue_tImagedownloadqueue=Dispatch_get_global_queue(Dispatch_queue_priority_default,0);Dispatch_async(Imagedownloadqueue,^{Nsurl*ImageURL=[NsurlURLWithString:@ "Http://test.com/test.png"];NSData*imagedata = [nsdata datawithcontentsofurl:imageurluiimage *image = [ uiimage imagewithdata:imagedata ]; dispatch_async (dispatch_get_main_queue (), ^{[imageview setimage : image//uikit must execute                

Of course, GCD, in addition to dealing with multithreading, there are many very good features, built on a strong kqueue, efficiency can also be guaranteed.

Four. Inter-thread communication

Inter-thread communication and interprocess communication are essentially similar. Inter-thread communication is the transfer of data between the two execution streams within the process, like the two parallel streams dug up a one-way flow long ditch, so that the water in one river can flow into another river, the matter is transferred.

1.performSelect on the Thread

The framework gives us a way to enforce a method in a thread, and if two non-main thread threads need to communicate with each other, you can first register your current thread object with a global object so that you can get the thread object from each other, and then you can use the following method to communicate between threads. Because the main thread is special, the framework provides a way to execute the thread directly.

@interfaceNSObject(nsthreadperformadditions)-(void)Performselectoronmainthread:(SEL)AselectorWithobject:(Id)ArgWaituntildone:(BOOL)WaitModes(Nsarray*)Array;-(void)Performselectoronmainthread:(SEL)AselectorWithobject:(Id)ArgWaituntildone:(BOOL)Wait;Equivalent to the first method with Kcfrunloopcommonmodes-(void)Performselector:(SEL)AselectorOnthread:(Nsthread*)ThrWithobject:(Id)ArgWaituntildone:(BOOL)WaitModes(Nsarray*)ArrayNs_available(10_5,2_0);-(void performselector: (SEL< Span class= "P" >) aselector onthread: (nsthread Span class= "o" >*) thr withobject: () arg waituntildone: (BOOL< Span class= "P" >) wait ns_available (10 _52_0);  Equivalent to the first method with Kcfrunloopcommonmodes  ...  @end                

2.Mach Port
Configuring a port-based Input Source in the Run pool section of Apple's thread Programming Guide has an example of using Mach Port for inter-thread communication. The essence of this is that the parent thread creates a Nsmachport object that is passed to the child thread as a parameter when the child thread is created, so that the thread can send a message to the passed-in Nsmachport object, and if it wants the parent thread to send a message to the child thread, Then the child thread can send a special message to the parent thread, passing in another Nsmachport object that it created, so that the parent thread holds the port object created by the child thread and can send a message to the Port object of the child thread.

Of course, the respective port object needs to set delegate and Schdule into the runloop of their thread, so that after the message, the delegate method that handles the port message is called, and you can process the message yourself.

Five. Runloop

Runloop literally is the meaning of running a loop, which is also good, it is really a loop concept, or exactly a thread in the loop. At the beginning of this article, it was mentioned that some programs are a circle, and this circle is essentially the so-called Runloop, which is a loop, but it is a loop that adds many features.
First the loop body needs to detect if there are events that need to be handled, and if so, go to sleep to save CPU time. So the focus is this need to deal with the event, in the Runloop, there are two types of events that need to be handled, one is the input source, the other is the timer, the timer is a good understanding of the operation that needs to be timed, the input source is divided into three categories: Performselector source, Port-based (Mach Port), and the source of the customization. You can add your own source when you are programming. Runloop also has the concept of observer observer, who can add their own observers to runloop to monitor the operation of the Runloop, and CFRunLoop.h defines the types of all observers:

EnumCfrunloopactivity{Kcfrunloopentry=(1<<0),Kcfrunloopbeforetimers=(1<<1),Kcfrunloopbeforesources=(1<< 2), kcfrunloopbeforewaiting =  (1 << 5 ), kcfrunloopafterwaiting =  (1  << 6), kcfrunloopexit =  ( Span class= "Mi" >1 << 7),  Kcfrunloopallactivities = 0x0fffffffu}; typedef enum cfrunloopactivity cfrunloopactivity;   

If you have used a select system call to write a program you can quickly understand the concept of Runloop event source, essentially the mechanism of event source and select is a multiplexed IO implementation, in a thread we need to do is not a single thing, such as the need to handle the fixed clock events, Need to handle the user's touch event, need to accept data from the remote end of the network, the need to do all the things to register to the event source, each time the beginning of the cycle to check whether the source of these events need to process the data, and some to deal with. Take a specific application for example, nsurlconnection network data request, the default is asynchronous way, its implementation principle is to add it as an event source after the creation of the current runloop, while waiting for the network response and network data acceptance of the process is in a newly created independent thread to complete, When the thread processes to a stage, such as getting a response from the other party or after accepting the network data, it notifies the previous thread to execute its associated delegate method. So this is often seen in cocoa, which is to scheduleInRunLoop:forMode: add it to the event source, and when an event is detected, the associated delegate method is called. For the corefoundation layer, the usual pattern is to create the input source and then add the input source through the CFRunLoopAddSource function to the Runloop, and the related callback function is called after the related event occurs. such as the use of cfsocket. In addition, there is a concept of running mode in Runloop, each running cycle must run in a certain mode, while the pattern exists in order to filter the event source and observer, only those event sources and observers that are consistent with the current Runloop run mode will be activated.

Each thread has its corresponding runloop, but the default non-main thread of Runloop is not running, you need to add at least one event source for Runloop, and then go to run it. In general, it is not necessary for us to enable thread runloop unless you have a long time to detect an event in a separate thread.

Introduction to Multithreading principle and Runloop in iOS

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.