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

How to implement sem_wait with timer..

99 views
Skip to first unread message

ldo...@wi.rr.com

unread,
Dec 28, 2001, 3:20:18 PM12/28/01
to
Hi all,

any idea how one could implement a sem_wait which expires in a given
time. Something on the lines of WaitForSingleObject with an associated
timer.

One way I was thinkming about was employing sem_trywait along with
SIGALARM signal. Any other simpler implementation ideas?

Thanks in advance.

LJ.

Nithyanandham

unread,
Dec 28, 2001, 3:55:10 PM12/28/01
to

ldo...@wi.rr.com wrote:

sem_trywait is a non-blocking call. Then why do you need a timer(SIGALRM)?

Are you talking about this:
sigaction() // to handel SIGALRM
setitimer()/alarm() // start timer
sem_wait() //
?

If your system supports 'sem_timedwait()', POSIX.1d function, use that.
http://www.usenix.org/publications/login/standards/22.posix.html

Otherwise, sem_wait()+timer should suffice.


--

Nithyanand.
Siemens, Bangalore, India.
(Opinions expressed are my own and do not reflect the opinions of my
employer, Siemens)

ldo...@wi.rr.com

unread,
Dec 28, 2001, 5:10:18 PM12/28/01
to
I will look into sem_timedwait. I do not think the bersion of Lynx I
am working with supports that.

I had to use sem_trywait after the time expires to check the semphore
is signaled. If i use sem_wait I block indefinetely other than EINTR.
Does sem_wait defined to be returned with an EINTR when a process is
interrupted with a signal.

LJ.

Kaz Kylheku

unread,
Dec 28, 2001, 5:38:31 PM12/28/01
to
In article <3c2cd30f...@news-server.wi.rr.com>, ldo...@wi.rr.com wrote:
>Hi all,
>
>any idea how one could implement a sem_wait which expires in a given
>time. Something on the lines of WaitForSingleObject with an associated
>timer.

If you are targetting Linux systems, and can assume glibc 2.2 or greater,
then you can just use the POSIX function sem_timedwait. For systems that
don't have it, you can fake this out somehow. For example, write your
own semaphore that is based on a mutex, condition and a counter. Then
pthread_cond_timedwait can be used as the basis for the timed wait.

>One way I was thinkming about was employing sem_trywait along with
>SIGALARM signal. Any other simpler implementation ideas?

This is a bad idea. Semaphore waits are not required to wake up due to
signals, and trying to bail sem_wait using a nonlocal exit from a signal
handler only lands you into undefined behavior.

Kaz Kylheku

unread,
Dec 28, 2001, 5:44:57 PM12/28/01
to
In article <3c2cec7f...@news-server.wi.rr.com>, ldo...@wi.rr.com wrote:
>I will look into sem_timedwait. I do not think the bersion of Lynx I
>am working with supports that.
>
>I had to use sem_trywait after the time expires to check the semphore
>is signaled. If i use sem_wait I block indefinetely other than EINTR.
>Does sem_wait defined to be returned with an EINTR when a process is
>interrupted with a signal.

This behavior is permitted, but not required. You cannot count on it to
be portable.

There is also no way to atomically unblock a signal and wait
on a semaphore. So there is therefore no race-free way to set a
signal-triggering timer and then wait on the semaphore. The signal can
go off first, and then the wait on the semaphore is indefinite.

Nithyanandham

unread,
Dec 28, 2001, 9:08:40 PM12/28/01
to

ldo...@wi.rr.com wrote:

> I will look into sem_timedwait. I do not think the bersion of Lynx I
> am working with supports that.
>
> I had to use sem_trywait after the time expires to check the semphore
> is signaled. If i use sem_wait I block indefinetely other than EINTR.

But, sem_wait might be interrupted by SIGALRM ie. delivery of SIGALRM will
interrupt the system call and sem_wait() will return EINTR.

> Does sem_wait defined to be returned with an EINTR when a process is
> interrupted with a signal.

Yes. But, as Kaz says it is not 100% portable.But, this is the way authors like

Richard Stevens have followed in their books..

Bil Lewis

unread,
Dec 29, 2001, 8:16:39 PM12/29/01
to

> >any idea how one could implement a sem_wait which expires in a given
> >time. Something on the lines of WaitForSingleObject with an associated
> >timer.

Let's go back a step...

What do you want to accomplish?

You imply that you have something that has real-time constraints and
that you want to... What do you want to do?

(Dollars to Donuts, semaphores are not what you want)

-Bil

Alexander Terekhov

unread,
Dec 31, 2001, 10:06:22 AM12/31/01
to

Kaz Kylheku wrote:
[...]

> If you are targetting Linux systems, and can assume glibc 2.2 or greater,
> then you can just use the POSIX function sem_timedwait. For systems that
> don't have it, you can fake this out somehow. For example, write your
> own semaphore that is based on a mutex, condition and a counter.
^^^^^^^^^^^^^
A single counter? I think that in order to implement
a sync.object according to POSIX definition of semaphore
one would need multiple counters (at least)... something
along the lines of (pseudo-code):

class semaphore
{
pthread_mutex_t mutex;
pthread_cond_t signal_occurred;
unsigned sem_cnt;
unsigned sem_waiting;
unsigned sem_signaled;

public:

void lock()
{
pthread_mutex_lock(&mutex);
if (0 != sem_cnt) {
--sem_cnt;
}
else {
++sem_waiting;
do {
// add proper cleanup!!!
pthread_cond_wait(&signal_occurred, &mutex);
// either ignore signal-"stealing" which
// could occur due to spurious wakeups/
// timeouts (for timedlock()) or just
// add some extra checking/handling here
// and in unlock()
} while (0 == sem_signaled);
--sem_signaled;
// add synch to unblock destructor thread,
// because POSIX says: "39080 It is safe to
// destroy an initialized semaphore upon which
// no threads are currently blocked.
}
pthread_mutex_unlock(&mutex);
}

void unlock()
{
pthread_mutex_lock(&mutex);
if (0 == sem_waiting) {
++sem_cnt;
pthread_mutex_unlock(&mutex);
}
else {
--sem_waiting;
++sem_signaled;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&signal_occurred);
}
}

~semaphore()
{
// add synch to wait for last signaled
// thread to acquire the mutex/retract
// waitor status...
}

};

or am I missing something?

regards,
alexander.

0 new messages