NSCondtion有多个线程

时间:2015-10-18 12:47:02

标签: objective-c locking signals nscondition ios-multithreading

方法1:

 - (void) method1
 {
    [_condition lock];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
         //Fetach data from remote, when finished call method2
         [self fetchData]; 
    });

    [_condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:30.0]];

    // Do something.
    [_condition unlock];
}

方法2:

- (void) method2
 {
    [_condition lock];
    [_condition signal];
    [_condition unlock];
}

如果线程1 在method1中,则执行[_condition waitUtilDate ...];会解锁其锁定。 线程2 进入此区域,并通过执行[_condition waitUtilDate ...]等待该条件。

主题1 主题2 排队阻止(请求1 请求2 )以获取相同内容来自远程的数据。当请求1 完成时,它会调用method2来发出_condition:

信号

我的问题是:

  • 将发出信号,主题1 主题2
  • '因为请求1 请求2 正在做同样的事情,我可以发信号通知两个线程(broadcast)并取消请求2 请求1 完成时。但是,更好的方法是在请求1 发出后拒绝线程2 进入关键区域。但是在进入关键区域之前我不会锁定两次。那我该怎么办?

感谢。

1 个答案:

答案 0 :(得分:0)

如果您正在尝试阻止重复请求,则可以使用您在启动请求时设置的布尔标志执行此操作,然后在完成后清除。您可以使用互斥锁/信号量/ NSLock /等保护您的关键区域。

[_lock lock];
if (_fetching) {
   [_lock unlock];
   return;
}

_fetching = YES;

[self startRequestWithCompletion: ^{ 
   [_lock lock];
   _fetching = NO;
   [_lock unlock]; 
}];

[_lock unlock];

或者你可以使用NSOperationQueue和NSOperation来更优雅地处理它。在开始新操作之前,您需要测试队列以查看是否有任何待处理或正在运行的操作。

if (_operationQueue.operationCount)
    return;

[_operationQueue addOperationWithBlock: ^{
    // get your data
}];

如何执行此操作实际上取决于您正在获取的内容以及响应是否可能会根据输入数据进行更改。例如,我广泛使用NSOperations来管理后台计算。但是,用户输入可能会更改这些计算的结果并使之前的任何工作无效。我继续参考NSOperation本身,所以我可以取消它并在适当的时候重新启动一个新的。