Unix Programming - Pthreads + Multiple sleep()

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > March 2004 > Pthreads + Multiple sleep()





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Pthreads + Multiple sleep()
Jeff Rodriguez

2004-03-18, 9:45 am

I'm tryin to use the sleep() function simultaneously in two threads. Now I do
understand this probably won't ever work since "Sleep may be implemented with
SIGALRM" yadda yadda. So I was wondering if anyone had a workaround for this?

Am I just suppose to "while ( time < timeImWaitingFor ) {yield}" or is there a
better way to do this?

Thanks!
Jeff
Marc Rochkind

2004-03-18, 9:45 am


"Jeff Rodriguez" <newsgroup1@gurugeek.EXAMPLENOSPAM.com> wrote in message
news:D386c.102848$h23.52201@fed1read06...
> I'm tryin to use the sleep() function simultaneously in two threads. Now I

do
> understand this probably won't ever work since "Sleep may be implemented

with
> SIGALRM" yadda yadda. So I was wondering if anyone had a workaround for

this?
>
> Am I just suppose to "while ( time < timeImWaitingFor ) {yield}" or is

there a
> better way to do this?
>
> Thanks!
> Jeff


You're right, the problem is that sleep and any other system call that uses
signals isn't appropriate for use in more than one thread at a time, because
of the way signals are delivered. So, one way to do this that comes to mind
if you need N threads to sleep is to sleep in just one, block SIGALRM from
all threads but that one, and wait on a condition variable in the other N-1
threads that's signaled (with pthread_cond_signal) when the one sleeping
thread wakes up.

I'm sure some others here will suggest alternatives.

--
Marc Rochkind
"Advanced UNIX Programming" (publishing April 2004)
www.basepath.com/aup


Sean Burke

2004-03-18, 9:46 am


"Marc Rochkind" <rochkind@basepath.com> writes:

> "Jeff Rodriguez" <newsgroup1@gurugeek.EXAMPLENOSPAM.com> wrote in message
> news:D386c.102848$h23.52201@fed1read06...
> do
> with
> this?
> there a
>
> You're right, the problem is that sleep and any other system call that uses
> signals isn't appropriate for use in more than one thread at a time, because
> of the way signals are delivered. So, one way to do this that comes to mind
> if you need N threads to sleep is to sleep in just one, block SIGALRM from
> all threads but that one, and wait on a condition variable in the other N-1
> threads that's signaled (with pthread_cond_signal) when the one sleeping
> thread wakes up.
>
> I'm sure some others here will suggest alternatives.


You can use nanosleep() if your system has it.

Otherwise, you can always fall back on

select(0, NULL, NULL, NULL, &timeval).

-SEan

Jeff Rodriguez

2004-03-18, 9:46 am

Sean Burke wrote:

> "Marc Rochkind" <rochkind@basepath.com> writes:

--SNIP--
>
>
> You can use nanosleep() if your system has it.
>
> Otherwise, you can always fall back on
>
> select(0, NULL, NULL, NULL, &timeval).
>
> -SEan
>



How's portability on nanosleep() and select() acorss the various unicies?

I know FreeBSD has both, but what about systems like Linux, HURD, Solaris, etc.

Are there any potential problems with these two methods?

Thanks again,
Jeff
Sean Burke

2004-03-18, 9:46 am


Jeff Rodriguez <newsgroup1@gurugeek.EXAMPLENOSPAM.com> writes:

> Sean Burke wrote:
>
> --SNIP--
>
>
> How's portability on nanosleep() and select() acorss the various unicies?
>
> I know FreeBSD has both, but what about systems like Linux, HURD, Solaris, etc.
>
> Are there any potential problems with these two methods?


For portability, select() is definitely your best choice.
nanosleep() is available on Solaris 8 and Linux of recent
vintage, but I'm not sure how far back it goes.

As for caveats, both calls can be interrupted by a
signal, so if it's important to sleep out the full
interval, you'll need to check for that.

-SEan





David Schwartz

2004-03-18, 1:39 pm


"Sean Burke" <foobar@mystery.org> wrote in message
news:x765d2fw67.fsf@bolo.xenadyne.com...

> For portability, select() is definitely your best choice.
> nanosleep() is available on Solaris 8 and Linux of recent
> vintage, but I'm not sure how far back it goes.
>
> As for caveats, both calls can be interrupted by a
> signal, so if it's important to sleep out the full
> interval, you'll need to check for that.
>
> -SEan



Here's what the 'Sleep' function in one of my portable libraries looks
like. It does have one caveat however, for full portability you are only
supposed to use it to sleep for intervals less than a second or in units of
full seconds (because of the fallback to sleep/usleep). It does not
guarantee to sleep for the full time nor does it tell you whether it was
interrupted or not. It's here just as an example.

void Sleep(unsigned milliseconds)
{
#if defined(PTH)
pth_yield(NULL);
pth_usleep(milliseconds*1000);
#elif defined(NANOSLEEP)
struct timespec t;
t.tv_sec=milliseconds/1000;
t.tv_nsec=(milliseconds%1000);
t.tv_nsec*=1000000ul;
nanosleep(&t, NULL);
#elif defined(OSF1)
struct timespec t;
t.tv_sec=milliseconds/1000;
t.tv_nsec=(milliseconds%1000);
t.tv_nsec*=1000000ul;
pthread_delay_np(&t);
#elif defined(NO_USLEEP)
struct timeval t;
t.tv_sec=milliseconds/1000;
t.tv_usec=(milliseconds%1000)*1000;
select(0, NULL, NULL, NULL, &t);
#else
int seconds, microseconds;
seconds=milliseconds/1000;
microseconds=(milliseconds%1000)*1000;
if(seconds) sleep(seconds);
if(microseconds) usleep(microseconds);
#endif
}

DS



Dragan Cvetkovic

2004-03-18, 1:39 pm

"David Schwartz" <davids@webmaster.com> writes:

[snip]

> Here's what the 'Sleep' function in one of my portable libraries looks
> like. It does have one caveat however, for full portability you are only
> supposed to use it to sleep for intervals less than a second or in units of
> full seconds (because of the fallback to sleep/usleep). It does not
> guarantee to sleep for the full time nor does it tell you whether it was
> interrupted or not. It's here just as an example.
>
> void Sleep(unsigned milliseconds)
> {
> #if defined(PTH)
> pth_yield(NULL);
> pth_usleep(milliseconds*1000);


[snipped the rest]

Just out of curiosity and not knowing anything about PTH, are you really
supposed to yield your executing before going to sleep? Or does pth_yield()
behave differently?

Bye, Dragan

--
Dragan Cvetkovic,

To be or not to be is true. G. Boole No it isn't. L. E. J. Brouwer

!!! Sender/From address is bogus. Use reply-to one !!!
David Schwartz

2004-03-18, 1:39 pm

NNTP-Posting-Host: joelkatz8.goldrush.com
X-Trace: nntp.webmaster.com 1079629226 13332 206.171.168.138 (18 Mar 2004 17:00:26 GMT)
X-Complaints-To: usenet@nntp.webmaster.com
NNTP-Posting-Date: Thu, 18 Mar 2004 17:00:26 +0000 (UTC)
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.2055
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2055
X-RFC2646: Format=Flowed; Original
Xref: intern1.nntp.aus1.giganews.com comp.unix.programmer:144548


"Dragan Cvetkovic" <me@privacy.net> wrote in message
news:lmhdwmb09o.fsf@privacy.net...
>
> [snipped the rest]
>
> Just out of curiosity and not knowing anything about PTH, are you really
> supposed to yield your executing before going to sleep? Or does
> pth_yield()
> behave differently?



I believe this was so the 'Sleep(0);' would do the same thing on PTH as
it does on other threading platforms. My recollection is that
'pth_usleep(0);' would not yield. On PTH, yielding is important because any
ready-to-run thread can be yielded to. (On POSIX threads, for example, a
ready-to-run thread may be running on another CPU and hence can't be yielded
to.)

Some code in other places does the equivalent of:

Lock();

if(ResourceIsAvailable()) UseIt();

else

{

Unlock() Sleep(0); Lock();

if(ResourceIsAvailable()) UseIt();

else DoThingsTheHardWay();

}

Unlock();

Without that change, on PTH, the second test was never true and we
always did things the hard way.

DS



Dragan Cvetkovic

2004-03-18, 3:35 pm

"David Schwartz" <davids@webmaster.com> writes:

> "Dragan Cvetkovic" <me@privacy.net> wrote in message
> news:lmhdwmb09o.fsf@privacy.net...
>
>
> I believe this was so the 'Sleep(0);' would do the same thing on PTH as
> it does on other threading platforms. My recollection is that
> 'pth_usleep(0);' would not yield.


Thanks for the explanation David.

Bye, Dragan

--
Dragan Cvetkovic,

To be or not to be is true. G. Boole No it isn't. L. E. J. Brouwer

!!! Sender/From address is bogus. Use reply-to one !!!
Geoff Clare

2004-03-19, 9:41 am

"Marc Rochkind" <rochkind@basepath.com> wrote, on Thu, 18 Mar 2004:

> do
> with
> this?


> You're right, the problem is that sleep and any other system call that uses
> signals isn't appropriate for use in more than one thread at a time, because
> of the way signals are delivered.


POSIX requires sleep() to be thread-safe (on implementations that
support threads). The "sleep may be implemented with SIGALRM" thing
only applies to non-threads implementations.

--
Geoff Clare <nospam@gclare.org.uk>
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com