Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
09-21-2005, 07:19 PM
|
#1
|
LQ Newbie
Registered: May 2004
Location: Germany, European Union
Distribution: SuSE 9.3 (heavily modified)
Posts: 5
Rep:
|
POSIX threads - pthread_cond_timedwait
Hi,
I have a strange thing here using the following code:
//////////////////////////////////////////////////////////////////////////////
bool WaitForCondition ( pthread_mutex_t *pMutex,
pthread_cond_t *pCond,
u32 uMicroSeconds )
{
struct timeval now;
struct timespec ts;
if (pthread_mutex_lock(pMutex))
return false;
gettimeofday(&now,NULL);
ts.tv_sec = now.tv_sec;
ts.tv_nsec = now.tv_usec+uMicroSeconds;
if (ts.tv_nsec>=1000000)
{
ts.tv_sec += ts.tv_nsec / 1000000;
ts.tv_nsec %= 1000000;
}
ts.tv_nsec *= 1000;
if (ETIMEDOUT==pthread_cond_timedwait(pCond,pMutex,&ts))
{
fprintf(stdout,"TIMEDOUT.\n");
pthread_mutex_unlock(pMutex);
return false;
}
pthread_mutex_unlock(pMutex);
return true;
}
//////////////////////////////////////////////////////////////////////////////
If I specify 200.000 microseconds to wait for a signaled cond variable, then it works. If I specify 300.000 microseconds, then the function always returns with "TIMEDOUT" printed.
Any help? (By the way: who the f**k specified the pthread_cond_timedwait function to need an ABSOLUTE time as the argument? Solaris has a non-portable workaround here!)
Thanks.
|
|
|
09-21-2005, 07:46 PM
|
#2
|
Member
Registered: Aug 2005
Location: Pittsburgh, PA, USA
Distribution: Redhat 9, OS X 10.4.x, Win2K
Posts: 85
Rep:
|
That code looks OK unless I'm missing something obvious. You're time math is tricky to look at but it seems like it's coming up with the right values. Could you post the part that's signalling the cond var (and use code tags)? Also, have you tried with any other timeout values? Perhaps something much larger, like a full second or two? Also you may want to try scheduling your entire process as realtime and seeing if it works... just for grins (although save your work first ). IIRC the scheduler intervals are usually on the order of somewhere around 10 milliseconds or so... even if it's not, it might be possible that something weird is going on in the kernel because in any case that shouldn't matter at all.
And, I agree, it is really annoying that you have to specify an absolute time. I always wondered what the rationale was for that -- you'd think there'd be a good reason but, you never know.
Jason
Last edited by JCipriani; 09-21-2005 at 07:53 PM.
|
|
|
09-24-2005, 01:44 PM
|
#3
|
LQ Newbie
Registered: May 2004
Location: Germany, European Union
Distribution: SuSE 9.3 (heavily modified)
Posts: 5
Original Poster
Rep:
|
Hi again,
thanks for the reply. The signalling code is:
Code:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
To be honest, I don't know if I need to acquire the mutex assigned to the condition variable in order to signal the condition variable? I am quite experienced with the Win32 synchronization functions but I am new to the POSIX threads. My function WaitForCondition should be the equivalent to the Win32 function "WaitForSingleObject".
I found more strange things using the function. Indeed, if I'm using other timeouts than 200 millisecs, then the pthread_cond_timedwait function always returns with ETIMEDOUT. That would not happen if the implementation would first check for the condition variable and then for the timeout. I think that it first checks for the timeout. This is another nasty thing with the POSIX synchronization functions!?
Do you have any idea for me? I think that this unreliable version of the function "WaitForCondition" doesn't work right on different machines at different CPU clocks (and also: with or w/o hyperthreading, dual cores, etc.).
Rgs, Ingo.
|
|
|
09-26-2005, 10:04 AM
|
#4
|
Member
Registered: Aug 2005
Location: Pittsburgh, PA, USA
Distribution: Redhat 9, OS X 10.4.x, Win2K
Posts: 85
Rep:
|
I'm assuming the mutex you are locking around pthread_cond_signal is the same mutex that you are passing to WaitForCondition? You do need to lock the mutex around both the signal and the timedwait call, this "avoids the race condition where a thread prepares to wait on a condition variable and another thread signals the condition just before the first thread actually waits on it." (from man page).
Is it possible that you have more than one thread waiting on that same condition variable? The pthread_cond_signal function will only awaken -one- thread that is waiting on the condition variable, not all of them. The pthread_cond_broadcast function will awaken all of them. If you have another thread waiting on that condition as well it's possible that it is getting awoken while the thread you care about isn't.
In my experience, POSIX threads have been pretty reliable. Granted their could be bugs in the implementation but if it was an actual bug in the thread library that is causing the problems you were seeing, you'd wonder how any of the threading was functional at all. It seems like there must be something else weird going on with your program rather than a problem with pthreads....
Like I said though, unless I'm missing something really obvious that still all seems OK.... are there any other threads running? The pthread_cond_signal vs. pthread_cond_broadcast thing is the best I can come up with.
|
|
|
09-26-2005, 10:18 AM
|
#5
|
LQ Newbie
Registered: May 2004
Location: Germany, European Union
Distribution: SuSE 9.3 (heavily modified)
Posts: 5
Original Poster
Rep:
|
Hi,
only one thread is waiting for the condition.
I could not correct the problem until now. Different timeouts yield to different error conditions!
I modified my code entirely to handle events in POSIX threads by improving the signal facility of my program.
A global signal dispatcher dispatches signals either to the primary LWP or to any subsequent LWPs linked as a double-linked list upon creation. This mechanism works reliable using SIGUSR1 and SIGUSR2.
You're right: I don't have any problems with the POSIX threads in general except for the 'pthread_cond_timedwait' problem I mentioned earlier.
Thanks so far.
|
|
|
09-26-2005, 11:33 AM
|
#6
|
Member
Registered: Aug 2005
Location: Pittsburgh, PA, USA
Distribution: Redhat 9, OS X 10.4.x, Win2K
Posts: 85
Rep:
|
I'm glad you got your program working but I'm still really curious about what your original problem was... if you ever get around to it you should try writing a minimal test program that shows the same behavior. Anyways, sorry I couldn't give any better advice!
Jason
|
|
|
All times are GMT -5. The time now is 12:40 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|