以线程安全的方式启动和停止操作

时间:2010-10-25 08:10:04

标签: objective-c multithreading thread-safety

我有一个看起来有点像这样的简单类:

@protocol Recorder
@property(BOOL) isRunning;
- (void) start;
- (void) stop;
@end

方法实现:

- (void) start {
    if (running)
        return;
    …
    running = YES;
}

- (void) stop {
    if (!running)
        return;
    …
    running = NO;
}

我开始考虑线程安全问题。目前的解决方案不是线程安全的,对吧?怎么样:

- (void) start {
    @synchronized(self) {
        if (running)
            return;
        …
        running = YES;
    }
}

这是正确的,前提是-stop方法也是同步的吗?我不喜欢@synchronized引入的额外嵌套。显式锁定会有效吗?

- (void) stop {
    [startStopLock lock];
    if (running)
        return;
    …
    running = YES;
    [startStopLock unlock];
}

或者我可以做到这一点吗?

enum { Running, Stopped };
NSConditionLock *startStopLock;

- (void) start {
    if (![startStopLock tryLockWithCondition:Stopped])
         return;
    …
    [startStopLock unlockWithCondition:Running];
}

此解决方案是否正确?你会以不同的方式做事吗?

1 个答案:

答案 0 :(得分:1)

这是什么语言?你是对的,第一个版本不是线程安全的。

同步版本是线程安全的。使用显式锁定时,您需要注意不要错过早期返回路径上的解锁。

如果您可以访问锁定的xchg内在函数,则可以使用原子交换操作轻松完成。 cmpxchg也有效。

start() {
    if (locked_xchg(running, YES) == YES) {
        // the old value was YES, so nothing to do
        return
    }