美文网首页
面试的时候给自己挖坑(线程)

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

作者: 游城十代2dai | 来源:发表于2020-05-21 16:12 被阅读0次

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

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

    我打开 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 一定不是同一个线程(异步并行)

    相关文章

      网友评论

          本文标题:面试的时候给自己挖坑(线程)

          本文链接:https://www.haomeiwen.com/subject/tigzohtx.html