繁体   English   中英

中止所有dispatch_semaphore_wait

[英]Abort all dispatch_semaphore_wait

在iOS中,GCD提供了信号灯以同步对有限资源供应的访问。

在我的程序中,我正在从外部设备读取数据。 该外部设备可以断开连接,并且程序将永远不会再发出信号。 因此,我们最终遇到以下情况:

  • 线程1正在等待信号量

     if (dispatch_semaphore_wait(self.writeSem, /* 15s timeout */)) { 
  • 线程2知道没有等待会成功

最终, dispatch_semaphore_wait超时,返回NO并且线程1恢复运行。

我如何立即使此dispatch_semaphore_wait失败,以便线程1立即获得“ NO并继续他的生命? 我可以使用某种“取消信号量”吗?

如果没有额外的“机械”,信号量就是对此的错误抽象。 除了发出信号之外,没有“取消信号量等待”操作,并且在发出信号时,如果没有更多信息,您将不知道它是由于成功还是终止而发出信号。 因此,您可以添加一个外部标志,以指示信号是完成信号还是提前终止信号,但是您必须适当地保护该标志,以防止并发读写。

此处使用的规范原语是条件变量,标准的Cocoa示例将使用NSCondition。 一个简单的示例可能如下所示:

NSCondition* cond = [NSCondition new];
__block BOOL workSucceeded = NO;
__block BOOL subordinateFinished = NO;
NSTimeInterval timeout = 5.0;

// Waiter
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    [cond lock];
    while (!subordinateFinished)
    {
        if (![cond waitUntilDate: [NSDate dateWithTimeIntervalSinceNow: timeout]])
        {
            // Timed out...
            NSLog(@"Timed out waiting for work at: %@", [NSDate date]);
            break; // don't keep waiting
        }
        else if (workSucceeded)
        {
            // Signaled to indicate that work was done
            NSLog(@"Work finished at: %@", [NSDate date]);
        }
        else //if (!workSucceeded)
        {
            // Signaled to indicate premature termination.
            NSLog(@"Work prematurely terminated at: %@", [NSDate date]);
        }
    }
    [cond unlock];
});

// Actor
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"Work started at: %@", [NSDate date]);
    BOOL completed = NO;

    // Uncomment one of these to trigger each case
    // Finish on time:
    //sleep(1);
    //completed = YES;

    // Fail Early:
    //sleep(1);

    // Time out
    //sleep(timeout + 1);

    // ... and when done
    [cond lock];
    workSucceeded = completed;
    subordinateFinished = YES;
    [cond signal];
    [cond unlock];
});

这里要了解的重要事项是workSucceededsubordinateFinished受条件锁的保护,并且不持有锁的任何人都不会读写。 人们在初次接触NSCondition时常常不清楚的是,调用-wait-waitUntilDate:-signal的行为都会导致调用线程暂时放弃锁定,同时要了解,当在该线程上恢复执行时,它将再次保持锁。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM