Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safe static variables objective c

Is there a way in objective C that I can define a static int that is thread safe?

for example if I have class called Session that has:

static unsigned int session_id = 1000;

- (int) generateSessionID{
        return session_id++;
}

I am constructing session objects from different threads, each session object should have a unique id.

like image 367
Unis Avatar asked Oct 28 '10 02:10

Unis


2 Answers

If you're talking Cocoa, the mutex functionality there is provided by NSLock and NSRecursiveLock.

In order to properly protect non-atomic resource, you need these mutexes, lest multiple threads may try to change the data at the same time (leading to corruption) or use the data in a half-changed state (leading to invalid data).

Your code would look something like this:

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;
}

If you're not using Cocoa (or what little Cocoa programming I remember from my brief interlude with an iMac is so dimly remembered that it's near useless), just use the concept, translating it to whatever language or framework you have:

  • lock the mutex before using or changing a protected resource.
  • use or change the resource.
  • unlock the mutex.
  • bonus advice 1: lock the mutex as late as possible and unlock it as soon as possible.
  • bonus advice 2: only lock what you need so you avoid unnecessary delays.

Explaining that last point some more: if you synchronise on self for two totally unrelated things (say a session ID and a user ID), they will block each other despite the fact that it's not necessary to do so. I would prefer two separate mutexes to keep the granularity low.

Of course, if you only have a mutex on the session ID alone (but see below for caveat), feel free to use synchronized(self) but I'd prefer to do it my way so I wouldn't get caught out adding another protected resource later.

In any case (this is the caveat mentioned), you will probably find that synchronising on self would not adequately protect a static variable, which would be shared across multiple objects. The mutex should belong to the data rather than whatever is using it.

like image 33
paxdiablo Avatar answered Sep 29 '22 11:09

paxdiablo


I think you're better off using atomic operations to modify session_id. A previous question talks about atomic increment/decrement operations for OS X, and this page talks about the OSAtomic header file. Atomic operations on integers, something that's readily hardware-supported, will probably be substantially faster than using locking constructs.

like image 111
Wyatt Anderson Avatar answered Sep 29 '22 11:09

Wyatt Anderson