非GCD环境中的GCD dispatch_semaphore

时间:2013-06-24 04:10:17

标签: objective-c multithreading grand-central-dispatch semaphore

我有一个Objective-C应用程序,它使用一个通过[NSThread detachNewThreadSelector]生成的显式后台线程。此后台线程是一个HTTP流demux,它生成视频和音频帧并将它们放在两个专用的对象队列中。除初始大小外,这些队列是相同的。他们使用NSLock和一对dispatch_semaphores来实现阻塞队列。这就是主要的5个操作的实现方式:

- (id) init:(uint)queueSize {
    queue = [[NSMutableArray alloc] initWithCapacity:queueSize];
    freeSlots = dispatch_semaphore_create(queueSize);
    objectsReady = dispatch_semaphore_create(0);
    lock = [[NSLock alloc] init];

    return [super init];
}

- (void)dealloc {
    NSLog(@"BlockingQ is being destroyed");
}

- (id) dequeue {
    dispatch_semaphore_wait(objectsReady, DISPATCH_TIME_FOREVER);
    [lock lock];
    id anObject = [queue objectAtIndex:0];
    [queue removeObjectAtIndex:0];
    [lock unlock];
    dispatch_semaphore_signal(freeSlots);

    return anObject;
}

- (void) enqueue:(id)element {
    dispatch_semaphore_wait(freeSlots, DISPATCH_TIME_FOREVER);
    [lock lock];
    [queue addObject:element];
    [lock unlock];
    dispatch_semaphore_signal(objectsReady);
}

- (uint) count {
    [lock lock];
    uint ret = [queue count];
    [lock unlock];
    return ret;
}

当时间停止播放时,我通知后台线程它需要停止然后我等待它终止。完成后,我尝试清理队列 做这样的事情:

- (void) clear {
    [lock lock];
    [queue removeAllObjects];
    while (dispatch_semaphore_wait(objectsReady, DISPATCH_TIME_NOW) == 0)
        dispatch_semaphore_signal(freeSlots);
    [lock unlock];
}

while循环的目的是“平衡”等待/信号调用,并确保当它们的值等于其初始值时释放两个信号量。我从阅读这个讨论中选择了它:Why does this code cause "EXC_BAD_INSTRUCTION"?

然而,当其中一个队列被破坏时,即使这个循环也不会使我免于崩溃。调试器显示的汇编代码片段几乎与上面链接中显示的相同。

所以,我的问题是:

  1. 将GCD信号量与NSThreads混合是否合法?
  2. 如何确保信号量处于良好状态以便销毁?
  3. 非常感谢!

0 个答案:

没有答案