The problem with POSIX semaphores process mutex using signals is required

Source: Internet
Author: User
Tags posix
  • From: http://charette.no-ip.com: 81/programming/2010-01-13_posixsemaphores/# Problem
  • The problem with POSIX semaphores
Summary

It has been a number of years since I 've used named semaphores. it cocould be that the last time I used a named semaphore was back in my OS/2 days. but I recently needed to coordinate some work between several applications running in a Linux environment, and named semaphores was the right solution.

Or so I thought...

Here is what I discovered, which hopefully explains why POSIX named semaphores as implemented in Linux are not working for me:

IPC

I was a bit confused when I started looking into inter-process communication on Linux systems. it took me a while to understand that we have 2 different IPC systems: the old traditional sysv-based IPC, and the new POSIX-based IPC.

The sysv semaphores are in # include <sys/SEM. h>. This includes des:

  1. Int semctl (INT, Int, Int ,...);
  2. Int semget (key_t, Int, INT );
  3. Int semop (INT, struct sembuf *, size_t );

Meanwhile, the new POSIX semaphores are in # include <semaphore. h>. A partial list of this API includes:

  1. Int sem_close (sem_t *);
  2. Sem_t * sem_open (const char *, Int ,...);
  3. Int sem_post (sem_t *);
  4. Int sem_wait (sem_t *);

Of particle importance to note is the sysv IPC command-line tools such as ipcmk, IPCS and ipcrm will not work with POSIX semaphores, though that is actually of minimal importance when trying to write self-contained C/C ++ applications.

Using semaphores

Opening a POSIX named semaphore is very simple. Note the following source code extract:


# Include <semaphore. h> // POSIX semaphores
# Include <fcntl. h> // semaphore flags: O _ * Constants
# Include <sys/STAT. h> // semaphore modes: S _ * Constants

Sem_t * SEM = sem_open ("/mytestsemaphore ",
O_creat | // create if it does not already exist
O_cloexec, // close on Execute
S_irusr | // user permission: Read
S_iwusr, // user permission: Write
1); // initial value of the semaphore


The problemto wait on the semaphore, you 'd call sem_wait (SEM) and to release it sem_post (SEM ).

 

In a simple scenario, all of this works very well. client Applications Open/create the semaphore, call sem_wait () when it is needed, and then sem_post () when finished. but in non-trivial, embedded and/or inclucial software, where you have to be prepared for and recover from external signals, there is a problem. there are at least two signals that cannot be caught: sigkill and sigstop.

Unfortunately, if a client application has es one of these signals between the call to sem_wait () and sem_post (), the semaphore is now unusable. or, at the very least, you're leaking one count every time this happens. if your initial semaphore count is 1, then a single instance of someone sending sigkill to a client application will starve all other clients waiting for that semaphore.

What I was expecting is for either the semaphore to be auto-posted back when the application gets cleaned up -- somewhat like open files get automatically closed and memory freed -- or for an additional SEM _* () API that a watcher can query to determine when this situation has occurred. if there was a reliable way to determine that an application had been killed between the two CILS, the watcher itself cocould decide tosem_post () and "Recover" The Lost semaphore.

Note that old sysv-style semaphore do have a way to cleanup after themselves to prevent this type of problem. the sem_undo flag can be specified which causes changes to the semaphore to be reverted if the application terminates abnormally. sadly, this is specific to sysv and does not apply to POSIX semaphores.

Alternatives

Depending on how the semaphore is used, there may be alternatives to POSIX semaphores:

  • Sysv semaphores (though this feels like a step backwards ...!)
  • Other resources which are automatically cleaned up when a process is terminated:
    • Sockets bound to a participant Port
    • File locks

Without adding much more complexity, the socket and file solutions only work when the semaphore is Boolean, used like a "named mutex ". the file lock solution proved to be adequate for what I was working on. this alternative solution caused me to replace all of my callto sem_wait () and sem_post () with callto lockf (...).

FD = open (filename,
O_rdwr | // open the file for both read and write access
O_creat | // create file if it does not already exist
O_cloexec, // close on Execute
S_irusr | // user permission: Read
S_iwusr); // user permission: Write

Lockf (FD, f_tlock, 0); // lock the "semaphore"

// Do some work here

// Note that close () Automatically releases the file lock
// So technically the call with f_ulock is not necessary
Lockf (FD, f_ulock, 0 );

Close (FD );

This is still not a perfect solution since the lock can be circumvented by manually deleting the lock file. but in my case, the likelyhood of an uncaught signal was higher and more devastating than someone removing the lock file. remember to check return values for errors, especially after open () and the first lockf () to ensure you 've waited on the "semaphore ".

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.