美文网首页
『ios』保活线程中运用信号量导致的死锁问题。

『ios』保活线程中运用信号量导致的死锁问题。

作者: butterflyer | 来源:发表于2021-08-19 17:09 被阅读0次

    保活线程中调用信号量会发生什么?
    看看下面这个例子。

    @property (nonatomic, strong)NSThread *thread;
    @property (nonatomic, strong)dispatch_semaphore_t semap;
    
    self.thread = [[NSThread alloc] initWithBlock:^{
            
           [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
    
           [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    
     }];
    [self.thread start];
    self.semap = dispatch_semaphore_create(0);
    [self performSelector:@selector(threadTest) onThread:self.thread withObject:nil waitUntilDone:YES];  
        
        
    
    - (void)threadTest{
        
        dispatch_async(dispatch_get_main_queue(), ^{
    
            NSLog(@"11");
            dispatch_semaphore_signal(self.semap);
            
        });
        dispatch_semaphore_wait(self.semap, DISPATCH_TIME_FOREVER);
        
        NSLog(@"%@",[NSThread currentThread]);
    }
    

    上面这段代码的执行结果是什么呢?
    用心想一下。
    实际运行结果,是会卡在 dispatch_semaphore_wait(self.semap, DISPATCH_TIME_FOREVER);这个上面。
    不会走 dispatch_async(dispatch_get_main_queue() 的方法。走最后一行代码。

    但是如果不包活线程,直接调用,那么能正常打印。

    self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadTest) object:nil];
     [self.thread start];
    

    这样搞,就真的很奇怪了。

    于是尝试了把dispatch_async(dispatch_get_main_queue(),改为dispatch_async(dispatch_get_global_queue(0, 0),发现先打印了 NSLog(@"11");于是我就在考虑是不是发生了死锁。

    然后看到performSelector这个方法,在前面设计线程保活的时候,用到过waitUntilDone这个参数。
    waitUntilDone 一个布尔值,指定当前线程是否阻塞,直到在指定线程上的接收器上执行指定选择器之后。 指定 YES 来阻塞这个线程; 否则,指定 NO 以立即返回此方法。
    当我把waitUntilDone:NO,发现问题就解决了。

      [self performSelector:@selector(threadTest) onThread:self.thread withObject:nil waitUntilDone:NO];
    

    原因是什么呢?
    waitUntilDone == YES 导致主队列的方法必须等待threadTest执行完,才能继续往下执行,而threadTest执行完,又要等待加入dispatch_async(dispatch_get_main_queue(), ^{}中的方法执行完,才能执行。这样就形成了死锁。

    相关文章

      网友评论

          本文标题:『ios』保活线程中运用信号量导致的死锁问题。

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