线程安全的静态变量目标c

Uni*_*nis 9 objective-c thread-safety

在目标C中是否有一种方法可以定义一个线程安全的静态int?

例如,如果我有一个名为Session的类,它具有:

static unsigned int session_id = 1000;

- (int) generateSessionID{
        return session_id++;
}
Run Code Online (Sandbox Code Playgroud)

我正在从不同的线程构造会话对象,每个会话对象应该具有唯一的ID.

Wya*_*son 9

我认为你最好使用原子操作来修改session_id.一个先前的问题有关OS X单位递增/递减操作会谈,这个页面对会谈OSAtomic的头文件.整数上的原子操作,很容易受硬件支持,可能比使用锁定结构快得多.


pax*_*blo 7

如果您在谈论可可,则其中的互斥功能由NSLock和提供NSRecursiveLock

为了正确地保护非原子资源,您需要这些互斥体,以免多个线程可能试图同时更改数据(导致损坏)或以半更改状态使用数据(导致无效数据)。

您的代码如下所示:

static NSLock session_id_lock;
static unsigned int session_id = 1000;

- (int) generateSessionID{
    int new_id;
    [myLock lock];
    new_id = session_id++;
    [myLock unlock];
    return new_id;
}
Run Code Online (Sandbox Code Playgroud)

如果您不使用Cocoa(或者在我短暂地回忆起与iMac的短暂接触中我记得的那一点点Cocoa编程几乎没有用),请使用概念,将其翻译为您拥有的任何语言或框架:

  • 在使用或更改受保护的资源之前,请锁定互斥锁。
  • 使用或更改资源。
  • 解锁互斥锁。
  • 奖励建议1:尽可能晚地锁定互斥锁并尽快将其解锁。
  • 额外建议2:仅锁定所需内容,以免造成不必要的延迟。

最后一点要多解释一下:如果您同步self两个完全不相关的内容(例如会话ID和用户ID),则尽管不需要这样做,但它们将彼此阻塞。我希望使用两个单独的互斥锁来保持较低的粒度。

当然,如果您仅在会话ID上只有一个互斥锁(但请注意,请参见下文),请随时使用,synchronized(self)但我希望以这种方式进行操作,这样以后就不会被添加其他受保护的资源所困扰。

在任何情况下(这是要指出的警告),您可能会发现同步启用self并不能充分保护静态变量,该静态变量将在多个对象之间共享。互斥锁应该属于数据,而不是使用它的对象。