首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NSCondition死锁

NSCondition死锁
EN

Stack Overflow用户
提问于 2011-08-01 17:39:45
回答 2查看 1.9K关注 0票数 1

我正在开发一个应用程序,它从HTTP连接接收数据,数据在传入时由一个或多个线程处理。我使用NSCondition来允许读取器线程等待传入的数据,并在数据可用时让连接线程广播它们,但我一直收到死锁,我不知道为什么。我要么误解了NSCondition的工作原理,要么我花了太长时间盯着它看,以至于我错过了其他一些东西。代码如下:

代码语言:javascript
运行
复制
// 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

EN

回答 2

Stack Overflow用户

发布于 2011-08-01 17:48:54

猜测,使用此方法

代码语言:javascript
运行
复制
- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error

在这里解锁条件。当您没有得到响应时,使用[condition unlock];

这条线路打不通电话。所以这些是锁定的,你的应用程序挂起了,所以试着使用这个建议。

票数 0
EN

Stack Overflow用户

发布于 2011-08-01 19:06:42

归根结底,我认为使用锁是一个复杂的解决方案。在主线程上使用同步IO是一个很大的禁忌,但在后台线程上使用同步IO是可以的,而且比处理异步请求更容易。

因此,如果你在后台线程上,阻塞当前线程等待IO线程的整个混乱只会让你痛苦不堪。替换为+[NSURLConnection sendSynchronousRequest:returningResponse:error:]并使用它即可。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6896596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档