views:

426

answers:

3

I'd like to use POSIX semaphores to manage atomic get and put from a file representing a queue. I want the flexibility of having something named in the filesystem, so that completely unrelated processes can share a queue. I think this plan rules out pthreads. The named posix semaphores are great for putting something in the filesystem that any process can see, but I can't find the standard CondWait primitive:

... decide we have to wait ....
CondWait(sem, cond);

When CondWait is called by a process it atomically posts to sem and waits on cond. When some other process posts to cond, the waiting process wakes up only if it can atomically decrement sem as well. The alternative of

... decide we have to wait ....
sem_post(sem);
sem_wait(cond);
sem_wait(sem);

is subject to a race condition in which some other process signals cond just before this process waits on it.

I hardly ever do any concurrent programming, so I thought I would ask SO: if I use a standard POSIX counting semaphore for the condition variable, is it possible that this race is benign?

Just in case anybody wants the larger context, I am building get and put operations for an atomic queue that can be called from shell scripts.

A: 

You are looking for: pthread_cond_wait, pthread_cond_signal, I think.
That's if you are using posix threads, then the pthread methods would supply the functionality of CondWait and Signal.
Look here for source code on multiprocess pthreads via shared memory.
http://linux.die.net/man/3/pthread_mutexattr_init
That's for Linux, but the documents are posix. They're similar to Solaris, but you'll want to peruse the man pages on your OS.

Chris
Can you explain how this is possible with multiple processes that do not share a common ancestor beyond init? I think pthreads have to all be started by the same process. Not easily adapted to shell scripts.
Norman Ramsey
+1  A: 

Since there are no other answers I will follow up with what I've learned:

  • Pthreads will not work with my application because I have processes without a common ancestor which need to share an atomic queue.
  • Posix semaphores are subject to the wakeup-waiting race, but because unlike classic condition variables they are counting semaphores, the race is benign. I don't have a proof of this claim but I have had a system running for two days now and working well. (Completely meaningless I know, but at least it meant I got the job done.)
  • Named Posix semaphores are difficult to garbage-collect from the filesystem.

To summarize, named Posix semaphores turned out to be a good basis for implementing an atomic queue abstraction to be shared among unrelated processes.

I would like to have a proof or a validated SPIN model, but as my need for the application is limited, it seems unlikely that I will write one. I hope this helps someone else who may want to use Posix semaphores.

Norman Ramsey
A: 

According to the POSIX standard, the set of semaphore routines is:

  • sem_close()
  • sem_destroy()
  • sem_getvalue()
  • sem_init()
  • sem_open()
  • sem_post()
  • sem_timedwait()
  • sem_trywait()
  • sem_unlink()
  • sem_wait()

The sem_trywait() and sem_timedwait() functions might be what you are looking for.

Jonathan Leffler
They are both useful functions but for purposes of determining if there's a race condition, they can be treated the same as sem_wait(). I believe there's a race but because POSIX semaphores are counting semaphores, the race is benign.
Norman Ramsey