objective-c - NS条件死锁

标签 objective-c multithreading cocoa

我正在开发一款应用程序,它从 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 中的锁,另一个线程正在等待获取 `连接:didReceiveData'。

我的理解是,[condition wait] 调用以原子方式解锁其内部互斥体并等待条件,因此多个等待线程不应阻止 connection:didReceiveData: 线程从获取和广播条件。

我错过了什么?

谢谢, J

最佳答案

猜猜,用这个方法

- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error

并在此解锁条件。当您没有收到响应时,[条件解锁];

此线路没有调用。因此这些已被锁定并且您的应用程序挂起,因此请尝试使用此建议。

关于objective-c - NS条件死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6896596/

相关文章:

macos - 如何在沙盒应用程序中添加调度?

objective-c - 在 watch os 2 运行时更新 wkinterfacecontroller 的方法

objective-c - 在 @try block 中调用函数是否会导致性能损失?

objective-c - 字体渲染不佳(Cocoa - Mac)

iphone - 如何创建具有多个SDK版本的iOS应用?

Java EE future 的空指针

C#,多线程 - 表单不更新

java - Swing:当 JTree 更新时间过长并卡住其他 GUI 元素时该怎么办?

cocoa - 编写 Firefox 和 Skype for Mac 时使用了 "Interface Builder"

c++ - SDL 错误 Undefined symbols for architecture x86_64 "_SDL_main"