Ios multi-thread operations (6)-GCD global queue and main queue column, iosgcd

Source: Internet
Author: User

Ios multi-thread operations (6)-GCD global queue and main queue column, iosgcd
By default, GCD provides global concurrent queues for the entire application, so you do not need to create them manually. The function for creating a global queue is

dispatch_queue_t q = dispatch_get_global_queue(long identifier, unsigned long flags)

The parameter type is long identifier: ios 8.0 tells the queue to execute the "service quality of service" of the task. The system provides the following parameters:
QOS_CLASS_USER_INTERACTIVE 0x21, User interaction (hope to be completed as soon as possible, the user is very expecting the results, do not put too much time-consuming operations) QOS_CLASS_USER_INITIATED 0x19, user expectation (do not put too time-consuming operations)
QOS_CLASS_DEFAULT 0x15, default (not for programmers, used to reset columns)
QOS_CLASS_UTILITY 0x11, utility (time-consuming operation, you can use this option)
QOS_CLASS_BACKGROUND 0x09, Background
QOS_CLASS_UNSPECIFIED 0x00, not specified
Priority before iOS 7.0
DISPATCH_QUEUE_PRIORITY_HIGH 2 high priority
DISPATCH_QUEUE_PRIORITY_DEFAULT 0 default priority
DISPATCH_QUEUE_PRIORITY_LOW (-2) low priority
DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN background priority
BACKGROUND indicates that you do not need to know when the task will be completed. If you select this option, the speed will be extremely slow, which is not conducive to debugging! Do not take too much responsibility for priority recommendations. It is the easiest to use to avoid priority inversion. Unsigned long flags: the official Apple documentation explains this: Flags that are reserved for future use. Tags are reserved for future use! Therefore, this parameter should always be set to 0. If ios8.0 is adapted to ios7.0, you can create a global queue as follows:
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
Try to use the global queue for asynchronous operations to see if it is concurrent execution. The following code:
Dispatch_queue_t q = dispatch_get_global_queue (0, 0); // 2. asynchronous execution of for (int I = 0; I <10; ++ I) {dispatch_async (q, ^ {NSLog (@ "% @ % d", [NSThread currentThread], i) ;}) ;}nslog (@ "come here ");


The running result is as follows:
Verification is correct. Now we simulate an operation. You need to log on first before you can perform two download operations. Both logon and download operations are time-consuming. Therefore, we need to enable a thread in the background, according to the actual situation, two download operations need to be executed concurrently. How can this problem be achieved? In this way, we will introduce the role of the synchronous function! The following code is available:
// 1. queue dispatch_queue_t q = dispatch_get_global_queue (0, 0); // 2. task void (^ task) () = ^ {dispatch_sync (q, ^ {NSLog (@ "Login % @", [NSThread currentThread]);}); dispatch_async (q, ^ {NSLog (@ "Download A % @", [NSThread currentThread]);}); dispatch_async (q, ^ {NSLog (@ "Download B % @", [NSThread currentThread]) ;};/// 3. asynchronous execution of task dispatch_async (q, task );


The execution result is as follows:
Again:
The results are all executed on the subthread regardless of the cause, and the logon is always at the beginning. We do not know which thread to download first. The above results are just a simple demonstration, if you start to download more basic books, you can see better results. In the MRC environment, the Global queue does not need to release memory.

Of course, GCD itself comes with a special serial queue. All tasks placed in the main queue column will be executed on the main thread. When the program is started, the main thread already exists, and the main queue column also exists. Therefore, the main queue column does not need to be created and only needs to be obtained, as shown below:
 dispatch_queue_t q = dispatch_get_main_queue();
Try to execute asynchronous tasks in the main queue:
Dispatch_queue_t q = dispatch_get_main_queue (); // 2. asynchronous execution of for (int I = 0; I <10; ++ I) {dispatch_async (q, ^ {NSLog (@ "% @-% d", [NSThread currentThread], i) ;}) ;}nslog (@ "thread sleep 1 s"); [NSThread sleepForTimeInterval: 1.0]; NSLog (@ "come here-% @", [NSThread currentThread]);

The execution result is as follows:
According to this, the asynchronous tasks in the main queue are executed on the main thread in sequence. In this example, the code on the main thread has not been completed yet, therefore, asynchronous tasks are executed after the tasks on the main thread are executed. What if a synchronization task is executed on the main thread? The following code:
// 1. queue dispatch_queue_tq = dispatch_get_main_queue (); NSLog (@ "now I'm here"); // 2. execute dispatch_sync synchronously (q, ^ {NSLog (@ "% @", [NSThreadcurrentThread]) ;}); NSLog (@ "come here ");


At this time, the printed result of the printer is as follows: the program can only execute the second code and cannot be executed. Why? The answer is that the main thread is blocked, that is, the deadlock !!! If there is a UI on the screen that interacts with the user at this time, the interaction function will also be lost, just like a crash !!! We should all know that a synchronization task has a feature that needs to be executed immediately as long as it is added to the queue, and there will always be one thread in the main queue-the main thread, at this time, the main thread is waiting for the main queue to schedule the synchronization task, and the main queue finds that there are still tasks not completed on the main thread, so the synchronization task will not be added to the main thread, this leads to mutual waiting (the main queue is waiting for the main thread to complete the existing tasks, and the main thread is waiting for the main queue to schedule synchronization tasks !), This is the so-called deadlock !!! What if a synchronization task needs to be executed in the main queue? We can use an asynchronous task to enclose a synchronization task and add it to the main queue! As follows:
// Global queue dispatch_queue_t q = dispatch_get_global_queue (0, 0); // task void (^ task) () = ^ {NSLog (@ "% @", [NSThread currentThread]); // execute the synchronization task dispatch_sync (dispatch_get_main_queue (), ^ {NSLog (@ "come here % @", [NSThread currentThread]) on the main column;}); NSLog (@ "hahaha % @", [NSThread currentThread]) ;}; // asynchronous execution task dispatch_async (q, task ); NSLog (@ "now I'm here-% @", [NSThread currentThread]);


The execution result is as follows:
The main thread is not blocked !!! "Now I'm here" is not displayed, but it will always come before the synchronization function in the main queue! The synchronization task in the main queue column is added to the asynchronous task in the global queue. The Global queue first executes the task on the main thread before executing the synchronization task!


Related Article

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.