面试的时候给自己挖坑(线程)

2020-05-21  本文已影响0人  游城十代2dai

面试官给我的第一个问题就是:

一个主线程任务等待另外两个子线程任务执行完成

我打开 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;
}

结果就是:

上一篇 下一篇

猜你喜欢

热点阅读