Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why is sem_wait() not undone when my program crashes?

1,720 views
Skip to first unread message

Sven C. Koehler

unread,
Feb 28, 2009, 8:40:49 AM2/28/09
to
Hello,

I am wondering whether it is possible to rewrite my code so that the
sem_wait() is automatically undone when my program crashes:

[a.c]
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>

int main() {
char *crash = 0x0;
sem_t *s = sem_open("gah", O_CREAT, 0777, 1);
printf("sem_wait\n");
sem_wait(s);
printf("crash\n");
crash[0] = 0x0;
printf("sem_post\n");
sem_post(s);
printf("done\n");
}

$ gcc -o a a.c -lpthread

When the named semaphore does not yet exists, the program crashes and
the next time it will hang in sem_wait()--any ideas? I was
considering using file locking instead of posix semaphores, but this
might be slower and probably doesn't work well with threads...

Sven C. Koehler

Jens Thoms Toerring

unread,
Feb 28, 2009, 10:30:05 AM2/28/09
to
Sven C. Koehler <skoe...@gmail.com> wrote:
> I am wondering whether it is possible to rewrite my code so that the
> sem_wait() is automatically undone when my program crashes:

I short, no. POSIX semaphores don't reset what you have done
to them once your progam exits, normally or forced. While in
some situations (like yours) this might be beneficial, it
would make other things impossible (like, for example, get-
ting a resource and passing it on to another process that
then does the post for it).

> [a.c]
> #include <stdio.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <semaphore.h>

> int main() {
> char *crash = 0x0;
> sem_t *s = sem_open("gah", O_CREAT, 0777, 1);
> printf("sem_wait\n");
> sem_wait(s);
> printf("crash\n");
> crash[0] = 0x0;
> printf("sem_post\n");
> sem_post(s);
> printf("done\n");
> }

> $ gcc -o a a.c -lpthread

> When the named semaphore does not yet exists, the program crashes and
> the next time it will hang in sem_wait()--any ideas?

Any ideas about what? As I understand it you bring about the seg-
mentation fault in the line with 'crash[0] = 0x0;' for demonstra-
tion purposes. Then the semaphore remains in the state it was at
that moment (locked) and when the next process tries to obtain it
it gets put to sleep indefinitely.

You might consider using SysV semaphores, they have the feature
that you seem to be looking for, e.g. allowing to undo all ope-
rations on a sempahore when the process exits. See semop() and
look for the SEM_UNDO flag.

> I was
> considering using file locking instead of posix semaphores, but this
> might be slower and probably doesn't work well with threads...

If file locking is slower or faster I can't tell. The way POSIX
semaphores seem to be implemented under Linux it could be that
file locks are actually faster. The current value of a POSIX
semaphore seems to be stored in a file (below /dev/shm/) and
doing a wait or post on it might require a read and/or write
operation on that file, which might be slower than just having
the kernel check for a file lock. But nothing but measuring
will tell you for sure.

And if there is any advantage when using threads is also unclear
to me - just as every thread could unlock a file, each thread
could post a semaphore (semaphores "belong" to the process as
a whole, not just a single thread, they are not like a thread
mutex).
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de

Joe Pfeiffer

unread,
Feb 28, 2009, 11:44:18 AM2/28/09
to
"Sven C. Koehler" <skoe...@gmail.com> writes:

> Hello,
>
> I am wondering whether it is possible to rewrite my code so that the
> sem_wait() is automatically undone when my program crashes:

Any particular reason not to rewrite your code so it doesn't crash?

Jens Thoms Toerring

unread,
Feb 28, 2009, 12:30:34 PM2/28/09
to

My understanding is that Sven put the "bug" in there delibera-
tely for demonstration purposes. And not only such a bug could
lead to the issue he describes but also e.g. a user doing a
'kill -9' on the process at the wrong moment - and there's
no fix for that (short of killing all luser;-)

David Schwartz

unread,
Feb 28, 2009, 2:30:58 PM2/28/09
to
On Feb 28, 5:40 am, "Sven C. Koehler" <skoeh...@gmail.com> wrote:

> When the named semaphore does not yet exists, the program crashes and
> the next time it will hang in sem_wait()--any ideas?  I was
> considering using file locking instead of posix semaphores, but this
> might be slower and probably doesn't work well with threads...

The same code that cleans up everything else can clean up the
semaphore. Presumably the semaphore is actually doing something. The
same code that deals with that something can deal with the semaphore.

DS

Rainer Weikusat

unread,
Mar 2, 2009, 2:07:24 AM3/2/09
to
j...@toerring.de (Jens Thoms Toerring) writes:
> Sven C. Koehler <skoe...@gmail.com> wrote:

[...]

>> I was
>> considering using file locking instead of posix semaphores, but this
>> might be slower and probably doesn't work well with threads...
>
> If file locking is slower or faster I can't tell.

It won't work (or shouldn't work). (fcntl-) file locks belong to a
process and a thread which attempts to establish a lock that would
conflict with one the process already owns should just cause the old
lock to be replaced.

> The way POSIX semaphores seem to be implemented under Linux it could
> be that file locks are actually faster. The current value of a POSIX
> semaphore seems to be stored in a file (below /dev/shm/) and
> doing a wait or post on it might require a read and/or write
> operation on that file,

A semaphore which should be used by multiple processes needs to reside
in a region of shared memory accessible to all of them. A fairly
straigh-forward way to implement this on top of existing facilities is
to use a file (on a tmpfs) and to have each process mmap this file
into its address space. Of course, executing 'suitable machine
instructions' to use this memory for synchronization among these
processes (and threads) does not require I/O-related system calls.
That would be a pretty mad toy implementation otherwise ...

John Hasler

unread,
Mar 2, 2009, 8:50:39 AM3/2/09
to
Jens Thoms Toerring writes:
> The way POSIX semaphores seem to be implemented under Linux it could be
> that file locks are actually faster. The current value of a POSIX
> semaphore seems to be stored in a file (below /dev/shm/) and doing a wait
> or post on it might require a read and/or write operation on that file,

That's a virtual file system. No disk reads or writes will occur.
However, I suspect you want unnamed semaphores anyway.

--
John Hasler
jo...@dhh.gt.org
Dancing Horse Hill
Elmwood, WI USA

0 new messages