Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mac OS X equivalent of CreateEvent() with named object for interprocess communication?

Tags:

c++

macos

ipc

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?

like image 648
binarybob Avatar asked Jan 16 '12 21:01

binarybob


1 Answers

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.

like image 155
binarybob Avatar answered Sep 29 '22 13:09

binarybob