我正在开发一个应用程序,它从HTTP连接接收数据,数据在传入时由一个或多个线程处理。我使用NSCondition来允许读取器线程等待传入的数据,并在数据可用时让连接线程广播它们,但我一直收到死锁,我不知道为什么。我要么误解了NSCondition的工作原理,要么我花了太长时间盯着它看,以至于我错过了其他一些东西。代码如下:
// lock = NSCondition ivar
// position = long long ivar
// writeDataToFile performs no locking but just writes the data to an NSHandle and logs in debug
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
[condition lock];
@try {
[self writeDataToFile:data];
position += [data length];
hasMoreData = YES;
} @finally {
[condition broadcast];
[condition unlock];
}
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
int statusCode = [httpResponse statusCode];
requestSuccess = (statusCode == 200);
[condition lock];
[condition broadcast];
[condition unlock];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error {
[condition lock];
hasMoreData = YES;
[condition broadcast];
[condition unlock];
}
- (void)waitForData {
[condition lock];
@try {
while( !hasMoreData ) {
[condition wait];
}
} @finally {
hasMoreData = NO;
[condition unlock];
}
}
现在,这通常是有效的,但偶尔我会看到应用程序挂起,一个示例显示一个线程在等待该条件,另一个线程等待获取waitForData
中的锁,另一个线程等待获取‘`connection:didReceiveData’中的锁。
我的理解是,[condition wait]
调用自动解锁其内部互斥锁并等待该条件,因此多个等待线程不应阻止connection:didReceiveData:
线程获取和广播该条件。
我遗漏了什么?
谢谢,J
发布于 2011-08-01 17:48:54
猜测,使用此方法
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
在这里解锁条件。当您没有得到响应时,使用[condition unlock];
这条线路打不通电话。所以这些是锁定的,你的应用程序挂起了,所以试着使用这个建议。
发布于 2011-08-01 19:06:42
归根结底,我认为使用锁是一个复杂的解决方案。在主线程上使用同步IO是一个很大的禁忌,但在后台线程上使用同步IO是可以的,而且比处理异步请求更容易。
因此,如果你在后台线程上,阻塞当前线程等待IO线程的整个混乱只会让你痛苦不堪。替换为+[NSURLConnection sendSynchronousRequest:returningResponse:error:]
并使用它即可。
https://stackoverflow.com/questions/6896596
复制相似问题