代码之家  ›  专栏  ›  技术社区  ›  zoul

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

  •  3
  • zoul  · 技术社区  · 15 年前

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

    @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 回复  |  直到 15 年前
        1
  •  1
  •   Dave Dunn    15 年前

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

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

    如果您有权访问锁定的xchg intrinsic,那么您可以通过原子交换操作相当容易地做到这一点。CMPxCHG也可以工作。

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