7

I'm looking for the simplest or most appropriate way on Mac OS X to simply "signal" or notify one process from another. Coming from a Windows background this could be achieved using something like the following.

In Process A:

// create named event
hCreatedEvent = CreateEvent(NULL, TRUE, FALSE, "MyUniqueNamedEvent");

// wait for it to be signalled
WaitForSingleObject(hCreatedEvent, INFINITE);

and then in Process B:

// open the existing named event
hOpenedEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "MyUniqueNamedEvent");

// signal it
SetEvent(hOpenedEvent);

So when the SetEvent call in Process B is executed, Process A would break out from WaitForSingleObject and do some work.

I don't need to actually send any data so I've ruled out things like Named Pipes (FIFO's) or sockets etc. as being a bit overkill (I've taken a look at this similar question, but as they need to send data, my question is slightly different). Equally, I won't know the PID of the other process (which is why I need some kind of shared object) so I can't use anything that would require that.

So far on my shortlist is:

  • POSIX Semaphores - using sem_open, sem_wait and sem_post to create/open, wait on and signal the event respectively. Appears fairly straighforward to use.
  • The BSD notify(3) functions - appears fairly straightforward to use, if not a little clunky to consume notifications.
  • The NSDistributedNotificationCenter or CFNotificationCenter functions - appears the most "Mac like" way of doing things and fairly straightforward. However, my code may needs to run as a dylib and according to this unanswered question, that may not work for me.

So, does anyone have any advice/tips/horror stories having used any of the above, or even more appropriate alternatives I haven't thought of to achieve what I want?

Community
  • 1
  • 1
binarybob
  • 3,529
  • 3
  • 23
  • 21

1 Answers1

4

So after a bit more digging I finally decided to go down the POSIX semaphores route, which seems to work for me, like so:

In Process A (waiting on the semaphore):

// create semaphore, fail if already exists
sem_t *sem = sem_open("MyUniqueSemaphore", O_CREAT | O_EXCL, 0666, 0);
if (sem != SEM_FAILED)
{
    // wait on semaphore
    if (sem_wait(sem) == 0)
    {
        // semaphore signalled!
    }

    // close our "handle" to the semaphore and remove it from the system
    sem_close(sem);
    sem_unlink("MyUniqueSemaphore");
}

Then in Process B (signalling the semaphore):

// open the existing semaphore created in process A
sem_t *sem = sem_open("MyUniqueSemaphore", 0);
if (sem != SEM_FAILED)
{
    // "signal" it
    sem_post(sem);

    // close our "handle" to the semaphore
    sem_close(sem);
}

The semaphore seems to also be an "auto reset" type (in Windows parlance) so reverts back to unsignalled once it has been signalled.

binarybob
  • 3,529
  • 3
  • 23
  • 21