The rule for sending a parallel queue using GCD when sleeping in one thread

The verification code is as follows:

dispatch_queue_t queue = dispatch_queue_create("sc", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:10]; NSLog(@"10s --- %@", [NSThread currentThread]); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{ NSLog(@"First: 5s --- %@", [NSThread currentThread]); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{ NSLog(@"Second: 5s --- %@", [NSThread currentThread]); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{ NSLog(@"Third: 5s --- %@", [NSThread currentThread]); }); 

Here I created a parallel queue and slept a single thread using the async method.

However, the output is:

 2016-03-26 12:17:57.164 TestPlayground[28188:551287] 10s --- <NSThread: 0x7fa080511730>{number = 2, name = (null)} 2016-03-26 12:17:57.165 TestPlayground[28188:551287] First: 5s --- <NSThread: 0x7fa080511730>{number = 2, name = (null)} 2016-03-26 12:17:57.166 TestPlayground[28188:551307] Second: 5s --- <NSThread: 0x7fa080704a80>{number = 3, name = (null)} 2016-03-26 12:17:57.166 TestPlayground[28188:551301] Third: 5s --- <NSThread: 0x7fa080511530>{number = 4, name = (null)} 

GCD seems to block the first thread for 10 seconds, and then starts to create a new thread for parallel work.

But if I just replace the self-created queue with a global parallel queue and do not change the next task

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // ... same as before 

The result is more reasonable.

 2016-03-26 12:23:29.496 TestPlayground[28320:558467] First: 5s --- <NSThread: 0x7ff473c08b80>{number = 4, name = (null)} 2016-03-26 12:23:29.496 TestPlayground[28320:558483] Second: 5s --- <NSThread: 0x7ff473f18c50>{number = 2, name = (null)} 2016-03-26 12:23:29.496 TestPlayground[28320:558471] Third: 5s --- <NSThread: 0x7ff473d0a7c0>{number = 3, name = (null)} 2016-03-26 12:23:34.030 TestPlayground[28320:558456] 10s --- <NSThread: 0x7ff473e218e0>{number = 5, name = (null)} 

What is the rule of sending to the GCD for this kind of work? And why is the created parallel queue itself distinguished by a global queue?


If I add a new task before bedtime

 dispatch_queue_t queue = dispatch_queue_create("sc", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"start --- %@", [NSThread currentThread]); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:10]; NSLog(@"10s --- %@", [NSThread currentThread]); }); // ... same as before 

Output signal

 2016-03-26 12:44:25.728 TestPlayground[28616:571502] start --- <NSThread: 0x7fb7c1604250>{number = 2, name = (null)} 2016-03-26 12:44:35.733 TestPlayground[28616:571511] 10s --- <NSThread: 0x7fb7c1422e40>{number = 3, name = (null)} 2016-03-26 12:44:35.734 TestPlayground[28616:571517] First: 5s --- <NSThread: 0x7fb7c16032d0>{number = 4, name = (null)} 2016-03-26 12:44:35.734 TestPlayground[28616:571511] Second: 5s --- <NSThread: 0x7fb7c1422e40>{number = 3, name = (null)} 2016-03-26 12:44:35.734 TestPlayground[28616:571552] Third: 5s --- <NSThread: 0x7fb7c1608950>{number = 5, name = (null)} 
+5
source share
1 answer

Consider the conclusion of the following:

 00:53:38.852 asdfasdfasdf[11650:2114104] start 00:53:38.854 asdfasdfasdf[11650:2114104] main <NSThread: 0x100206110>{number = 1, name = main} 00:53:38.854 asdfasdfasdf[11650:2114126] Enter sleep block 00:53:38.854 asdfasdfasdf[11650:2114127] bare async 00:53:48.858 asdfasdfasdf[11650:2114126] Sleep block done (10 seconds). 00:53:48.859 asdfasdfasdf[11650:2114126] dispatch_after() 5 --- <NSThread: 0x10020aa00>{number = 2, name = (null)} 

Thus, the sleeping thread does not block the call of blocks asynchronously located in the queue (even when the thread thread is on), but it blocks the execution of dispatch_after ().

What scares me. rdar: // 25373048

  dispatch_queue_t queue = dispatch_queue_create("sc", DISPATCH_QUEUE_CONCURRENT); NSLog(@"start"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"main %@", [NSThread currentThread]); dispatch_async(queue, ^{ NSLog(@"Enter sleep block"); [NSThread sleepForTimeInterval:10]; NSLog(@"Sleep block done (10 seconds)."); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{ NSLog(@"dispatch_after() 5 --- %@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"bare async"); }); }); [[NSRunLoop currentRunLoop] run]; 
+3
source

Source: https://habr.com/ru/post/1245808/


All Articles