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:
sem_open
, sem_wait
and sem_post
to create/open, wait on and signal the event respectively. Appears fairly straighforward to use.notify(3)
functions - appears fairly straightforward to use, if not a little clunky to consume notifications.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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With