GCD for iOS multi-thread Development (Part II) and ios multi-thread gcd

Source: Internet
Author: User

GCD for iOS multi-thread Development (Part II) and ios multi-thread gcd

This article explains what GCD is and how to use GCD. If you are interested, you can review "iOS multithreading development GCD (previous article)" and "iOS multithreading development GCD (middle article)".

To put it bluntly, let's first review the deadlock. The so-called deadlock refers to the competition for resources (such as data sources and memory) between two or more processes (threads) during execution, variables are not resources.

Cause of deadlock:

Conditions for deadlock formation:

In GCD, the main deadlock is that the current serial queue is synchronously executed in the current serial queue. The solution is to put the synchronous serial queue to another thread for execution. Before giving an example, let's review the task distribution and queue in GCD.

(1) Task Distribution

Task Distribution Method Description
Dispatch_sync () Synchronous execution. It is returned only after the scheduled task is completed, blocking the current thread.
Dispatch_async () Asynchronous execution, will return immediately, the scheduled task will be completed but will not wait for it to complete, does not block the current thread

(2) queue type

Queue type Description
Serial queue Only one task can be executed at a time, and the previous execution task must be completed.
Concurrent queue Multiple tasks can be executed concurrently at a time without waiting for the task to be completed.

(3) GCD queue type

GCD queue type Obtain Method Queue type Description
Main queue Dispatch_get_main_queue Serial queue Execute in Main Line
Global queue Dispatch_get_global_queue Concurrent queue Run in sub-Thread
User queue Dispatch_queue_create String merging is acceptable. Run in sub-Thread

From this we can conclude that:Serial and parallel operations are aimed at queues, while synchronous and asynchronous operations are aimed at threads!

Case Analysis:

1. synchronous execution encounters a serial queue

- (void)syncMain{        dispatch_queue_t queue = dispatch_get_main_queue();        NSLog(@"task1-%@",[NSThread currentThread]);        dispatch_sync(queue, ^{        NSLog(@"task2-%@",[NSThread currentThread]);    });        NSLog(@"task3-%@",[NSThread currentThread]);}

Print result:

2017-07-10 17:54:43.623 beck.wang[1405:182548] task1-<NSThread: 0x608000066000>{number = 1, name = main}

Analysis: deadlock.

Cause: From the printed results, we can see that task 1 is executed in the main thread, the main thread is a serial queue, the defined queue is also the main queue column, and dispatch_sync is the mark of synchronous execution, this means that task 3 can be executed only after the block is returned, and Task 1 is executing in the current main column. Task 3 can be released only after Task 3 is completed. This causes Task 3 to wait for the block to return, the block waits for Task 3 to complete the release of the main queue and deadlocks in the wait loop.

Extension: Will a deadlock occur when the sync function is used in the main thread "or" Will the deadlock occur when the sync function is used in the main thread and the serial queue is passed in at the same time? NO. It is obvious that the deadlock is not really understood! From the above case, we obviously know that the cause of the deadlock is queue blocking. So what if I customize a serial queue and don't compete with the main queue?

-(Void) syncMain {// note that the queue here is a custom serial queue instead of the master queue column dispatch_get_main_queue () dispatch_queue_t queue = dispatch_queue_create ("com. demo. serialQueue ", DISPATCH_QUEUE_SERIAL); NSLog (@" task1-% @ ", [NSThread currentThread]); dispatch_sync (queue, ^ {NSLog (@" task2-% @", [NSThread currentThread]);}); NSLog (@ "task3-% @", [NSThread currentThread]);}

Print result:

2017-07-10 18:07:15.134 beck.wang[1427:192164] task1-<NSThread: 0x600000074800>{number = 1, name = main}2017-07-10 18:07:15.135 beck.wang[1427:192164] task2-<NSThread: 0x600000074800>{number = 1, name = main}2017-07-10 18:07:15.135 beck.wang[1427:192164] task3-<NSThread: 0x600000074800>{number = 1, name = main}

Analysis: New threads are not enabled for sequential execution.

Cause: the queues executed by Task 1, Task 3, and task 2 are different and will not be blocked.

 

Ii. Parallel queue for Synchronous execution

- (void)syncConcurrent{        NSLog(@"task11-%@",[NSThread currentThread]);        dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSLog(@"task12-%@",[NSThread currentThread]);    });        NSLog(@"task13-%@",[NSThread currentThread]);}

Print result:

2017-07-10 18:15:11.957 beck.wang[1452:198567] task11-<NSThread: 0x608000071f00>{number = 1, name = main}2017-07-10 18:15:11.957 beck.wang[1452:198567] task12-<NSThread: 0x608000071f00>{number = 1, name = main}2017-07-10 18:15:11.957 beck.wang[1452:198567] task13-<NSThread: 0x608000071f00>{number = 1, name = main}

Analysis: New threads are not enabled for sequential execution.

Cause: the queues executed by Task 1, Task 3, and task 2 are different and will not be blocked.

Iii. asynchronous & synchronous combination

- (void)gcdTest{        dispatch_queue_t queue = dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL);        NSLog(@"task1-%@",[NSThread currentThread]);        dispatch_async(queue, ^{            NSLog(@"task2-%@",[NSThread currentThread]);                dispatch_sync(queue, ^{            NSLog(@"task3-%@",[NSThread currentThread]);        });                NSLog(@"task4-%@",[NSThread currentThread]);    });        NSLog(@"task5-%@",[NSThread currentThread]);}

 

Print result:

2017-07-10 18:29:23.976 beck.wang[1562:207413] task1-<NSThread: 0x608000063400>{number = 1, name = main}2017-07-10 18:29:23.976 beck.wang[1562:207413] task5-<NSThread: 0x608000063400>{number = 1, name = main}2017-07-10 18:29:23.976 beck.wang[1562:207460] task2-<NSThread: 0x608000067940>{number = 3, name = (null)}

Analysis: deadlock.

Cause: Task 2, Task 4, and task 3 are executed in the same queue. dispatch_sync determines that Task 4 can be executed only after Task 3 is completed and the current queue is occupied when Task 2 is executed, task 4 can be released only after Task 4 is completed. This causes Task 3 to wait for Task 4 to complete, and Task 4 to wait for Task 3 to return to each other. This is also a deadlock caused by queue congestion.

Extension: If the queue is changed to a custom concurrent queue or dispatch_sync is appended to a non-current queue (such as the main queue column), no deadlock will occur.

-(Void) gcdTest {dispatch_queue_t queue = dispatch_queue_create ("com. demo. serialQueue ", DISPATCH_QUEUE_SERIAL); NSLog (@" task1-% @ ", [NSThread currentThread]); dispatch_async (queue, ^ {NSLog (@" task2-% @", [NSThread currentThread]); // The main queue column is used here, instead of a custom serial queue, no deadlock will occur. Likewise, parallel queues do not deadlock dispatch_sync (dispatch_get_main_queue (), ^ {NSLog (@ "task3-% @", [NSThread currentThread]);}); NSLog (@ "task4-% @", [NSThread currentThread]);}); NSLog (@ "task5-% @", [NSThread currentThread]);}

Print result:

2017-07-10 18:38:20.214 beck.wang[1582:215721] task1-<NSThread: 0x608000069780>{number = 1, name = main}2017-07-10 18:38:20.214 beck.wang[1582:215721] task5-<NSThread: 0x608000069780>{number = 1, name = main}2017-07-10 18:38:20.214 beck.wang[1582:215779] task2-<NSThread: 0x618000069cc0>{number = 3, name = (null)}2017-07-10 18:38:20.217 beck.wang[1582:215721] task3-<NSThread: 0x608000069780>{number = 1, name = main}2017-07-10 18:38:20.217 beck.wang[1582:215779] task4-<NSThread: 0x618000069cc0>{number = 3, name = (null)}

 

4. In the above expansion case, the main thread is blocked.

-(Void) gcdTest {dispatch_queue_t queue = dispatch_queue_create ("com. demo. serialQueue ", DISPATCH_QUEUE_SERIAL); NSLog (@" task1-% @ ", [NSThread currentThread]); dispatch_async (queue, ^ {NSLog (@" task2-% @", [NSThread currentThread]); // although the main queue column is used here, the main queue column is blocked and the subsequent code becomes invalid: dispatch_sync (dispatch_get_main_queue (), ^ {NSLog (@ "task3-% @", [NSThread currentThread]);}); NSLog (@ "task4-% @", [NSThread currentThread]);}); NSLog (@ "task5-% @", [NSThread currentThread]); while (1) {// enters the while constant loop, main thread (main queue) blocking} NSLog (@ "task6-% @", [NSThread currentThread]);}

Print result:

2017-07-10 18:47:22.844 beck.wang[1657:223045] task1-<NSThread: 0x60000007afc0>{number = 1, name = main}2017-07-10 18:47:22.844 beck.wang[1657:223045] task5-<NSThread: 0x60000007afc0>{number = 1, name = main}2017-07-10 18:47:22.844 beck.wang[1657:223110] task2-<NSThread: 0x610000262700>{number = 3, name = (null)}

Analysis: when the main thread enters the infinite blocking status, task6, task3, and task4 cannot be accessed and are in the infinite waiting status.

 

PS: This article has some references. I wrote this blog post to better understand the deadlock of GCD. After all, good memory is not as good as bad writing! In my work, I will continue to complete the GCD deadlock situation. SO, this article is not complete .....

 

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.