On Mar 28, 2009, Jerry Krinock wrote: Thanks, Terry. I must be using them incorrectly then. My proof-of- concept demo tool alternately opens, and then unlink+closes the semaphore every few seconds.
If I crash the tool by clicking "Stop" in Xcode while it has the semaphore "open", then re-launch, the new process cannot open the same- named semaphore. But if I crash the tool after it has unlink+closed the semaphore, then the new process ^can^ open the semaphore.
Here is my code, with error and retry recovery removed for readability...
int main () { sem_t* descriptor ;
// Try to acquire semaphore descriptor = sem_open("MySemaphore", (O_CREAT|O_EXCL), S_IRWXU, 1) ; if (descriptor != SEM_FAILED) { // Do work ... // Work is done
sem_unlink("MySemaphore") ; sem_close(descriptor) ; }
return 0 ; }
Is this incorrect? I've seen code published where someone unlinked immediately after opening, but when I tried that, other processes could acquire the semaphore while the work was going on, which is no good.
If you insist on doing it this way, you could add a signal handler. In a trap handler for SIGSEGV and SIGBUS, call sem_unlink and sem_close. See man sigaction for info.
That said, this definitely isn't the right way to use a semaphore.... A semaphore is by nature cross-process, which means that the process quitting (or crashing) doesn't cause it to be destroyed. As such, you can't really use access to a semaphore as a gating mechanism in any useful way. The right way to do this is to treat the semaphore as a mutex, e.g.:
// Create a semaphore with an initial value of 1 if it does not exists or just open the existing semaphore if it does. descriptor = sem_open("com.mycompany.myproduct.mysemaphore", (O_CREAT), S_IRWXU, 1) ;
if (descriptor)) { // Wait until the semaphore value is greater than zero, then decrement the semaphore value. sem_wait(descriptor);
// Do work here.
sem_post(descriptor); sem_close(descriptor); }
If you do that, it should work as Terry describes. You probably should not be calling sem_unlink at all.
David
|