iPhone: How can I implement semaphore?

11,999

Solution 1

C apis can be found in sys/semaphore.h. use these in your objc wrapper/implementation.

this basic example is the first result when 'sem_trywait example' is googled. it shows you how you can use these apis.

then a minimal interface would take this form:

@interface MONSemaphore : NSObject
{
    sem_t semaphore;
}

- (int)close;
- (int)destroy;

/* .. and the rest of the interface you wrap and make public here .. */

@end

but it's likely that you will also want the object to abstract the init and destruct routines from the client.

Solution 2

If you definitely need an actual semaphore, probably the best thing to use is GCD's dispatch semaphores. I'd put an explanation in, but the code in the link is pretty simple. You should be able to follow it.

Basically, you create the semaphore with a parameter that indicates the number of concurrent instances of your resource you can have. Then threads that want to use the resource wait on the semaphore until one becomes available and signal it when they are done.

Consider using a dispatch queue or an NSOperationQueue instead with a concurrent limit of the number of instances of your resource. This is the approved Apple way of doing such things.

Solution 3

You should look into using NSLock or NSCondition if you want to handle the data protection and critical section yourself. You can also use the @synchronized directive. You can also just use the usual POSIX thread API if you fancy it although it's not recommended as Cocoa gives you plenty of higher level stuff which is simpler and nicer. This discussion was useful to me.

Solution 4

From Apple Docs (Threading):

Objective-C supports multithreading in applications. Therefore, two threads can try to modify the same object at the same time, a situation that can cause serious problems in a program. To protect sections of code from being executed by more than one thread at a time, Objective-C provides the @synchronized() directive.

The @synchronized()directive locks a section of code for use by a single thread. Other threads are blocked until the thread exits the protected code—that is, when execution continues past the last statement in the @synchronized() block.

The @synchronized() directive takes as its only argument any Objective-C object, including self. This object is known as a mutual exclusion semaphore or mutex. It allows a thread to lock a section of code to prevent its use by other threads. You should use separate semaphores to protect different critical sections of a program. It’s safest to create all the mutual exclusion objects before the application becomes multithreaded, to avoid race conditions.

Example:

Account *account = [Account accountFromString:[accountField stringValue]];

// Get the semaphore.
id accountSemaphore = [Account semaphore];

@synchronized(accountSemaphore) {
    // Critical code.
    ...
}
Share:
11,999
DeFlo
Author by

DeFlo

Updated on June 14, 2022

Comments

  • DeFlo
    DeFlo almost 2 years

    Can somebody explain how I can implement semaphore in Objective-C? I did a lot of google searching on the topic, but I haven't found anything understandable.

  • JeremyP
    JeremyP over 12 years
    A semaphore is not just a lock.
  • jbat100
    jbat100 over 12 years
    @JeremyP agreed, however if you are referring to counting semaphores (which can be locked/acquired and unlocked/signaled multiple times) then NSRecursiveLock should do the trick.
  • JeremyP
    JeremyP over 12 years
    @jbat100: NSRecusiveLock is not the same thing as a semaphore either.
  • jbat100
    jbat100 over 12 years
    @JeremyP could you tell me about the key difference? The definition I find is: "In computer science, a semaphore is a variable or abstract data type that provides a simple but useful abstraction for controlling access by multiple processes to a common resource in a parallel programming environment."
  • JeremyP
    JeremyP over 12 years
    @jbat100: A semaphore is typically implemented as a counter starting at an initial value. A process waiting on a semaphore tries to decrement the counter, if the counter is zero, it blocks until the counter has been incremented by some other process. When it's done with the semaphore, the process signals it which either increments the counter or, if a process is blocked on it, unblocks the rocess.
  • JeremyP
    JeremyP over 12 years
    @jbat100: A recursive lock is just a lock that won't cause you to block if you try to acquire it when you have already got it.
  • Gökhan Barış Aker
    Gökhan Barış Aker almost 12 years
    Couldn't find Account class anywhere. Do i have to implement my own, or is there a pre-implemented class available somewhere_
  • Nekto
    Nekto almost 12 years
    You could use any class for that purposes!
  • Paul de Lange
    Paul de Lange over 8 years
    Can you provide a reference to where it is documented as the Apple approved way?
  • JeremyP
    JeremyP over 8 years