面试官给我的第一个问题就是:
一个主线程任务等待另外两个子线程任务执行完成
我打开 Xcode, 由于视频面试共享桌面, 我怕运行 iOS 模拟器会卡, 所以选择了 Command Line Tool, 此时就挖坑了, 代码如下两种方式
void test1(void) {
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
sleep(1);
NSLog(@"print 1: %@", [NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
sleep(1);
NSLog(@"print 2: %@", [NSThread currentThread]);
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"print 3: %@", [NSThread currentThread]);
});
}
void test2(void) {
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_semaphore_t signal = dispatch_semaphore_create(1);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"print 1: %@", [NSThread currentThread]);
dispatch_semaphore_signal(signal);
});
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"print 2: %@", [NSThread currentThread]);
dispatch_semaphore_signal(signal);
});
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"print 3");
});
}
上面的代码在 iOS APP 上执行的顺序是 1,2 先执行顺序不固定, 然后再执行 3
上面的代码在 Command Line 上执行的顺序是 1,2 执行顺序不固定, 然后结束
, 这个打印不绝对, 因为都是异步执行很有可能一个打印都没有就结束了
为什么这样呢?
因为 Command Line 没有 Runloop, 也就是运行完即销毁了, 等不到异步任务结束
所以在 main 函数底部或者 test 函数底部添加如下代码即可:
[NSRunLoop.currentRunLoop addPort:NSPort.new forMode:NSDefaultRunLoopMode];
[NSRunLoop.currentRunLoop run];
借此机会改编一下我遇到的问题, 生成如下面试题:
// 在 Command Line Tool 中下面的代码打印顺序大该怎样, 并说出线程大概什么样子
int main(int argc, const char * argv[]) {
@autoreleasepool {
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_group_async(group, queue, ^{
sleep(1);
NSLog(@"print 1: %@", [NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
sleep(1);
NSLog(@"print 2: %@", [NSThread currentThread]);
});
dispatch_group_async(group, queue2, ^{
sleep(1);
NSLog(@"print 3: %@", [NSThread currentThread]);
});
dispatch_group_async(group, queue2, ^{
sleep(1);
NSLog(@"print 4: %@", [NSThread currentThread]);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"print 5: %@", [NSThread currentThread]);
});
}
return 0;
}
结果就是:
- 有可能什么都不执行就结束了
- 有可能执行了, 但是只执行了异步的, 也就是 123 会先执行但是顺序不一定, 4 一定是在 3 之后执行但不一定挨着。 queue 是并行队列, queue2 是串行的, 但是对于 queue 而言, queue2 也是并发的,所以 1、2 、3 顺序不确定, 3 执行后执行4。
- 线程方面, 5 一定主线程,3、4 同一个线程(串行),1、2 一定不是同一个线程(异步并行)
网友评论