具有多个线程的 NSCondtion
NSCondtion with multiple threads
方法一:
- (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) 从远程获取相同的数据。当 request 1 完成时,它调用 method2 来发出 _condition:
我的问题是:
- 哪个会被通知,线程 1 或 线程 2?
- ' 因为 request 1 和 request 2 正在做同样的事情,我可以向两个线程发出信号(
broadcast
)并在 请求 1 完成时取消 请求 2。但是,更好的办法是在请求1发出后,拒绝线程2进入临界区。但是在进入关键区域之前我无法锁定两次。那我该怎么办?
谢谢。
如果您试图防止重复请求,您可以使用在开始请求时设置的布尔标志来执行此操作,然后在完成后清除。你会用 mutex/semaphore/NSLock/etc.
保护你的关键区域
[_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 本身,这样我就可以取消它并在适当的时候重新启动一个新的。
方法一:
- (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) 从远程获取相同的数据。当 request 1 完成时,它调用 method2 来发出 _condition:
我的问题是:
- 哪个会被通知,线程 1 或 线程 2?
- ' 因为 request 1 和 request 2 正在做同样的事情,我可以向两个线程发出信号(
broadcast
)并在 请求 1 完成时取消 请求 2。但是,更好的办法是在请求1发出后,拒绝线程2进入临界区。但是在进入关键区域之前我无法锁定两次。那我该怎么办?
谢谢。
如果您试图防止重复请求,您可以使用在开始请求时设置的布尔标志来执行此操作,然后在完成后清除。你会用 mutex/semaphore/NSLock/etc.
保护你的关键区域[_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 本身,这样我就可以取消它并在适当的时候重新启动一个新的。