I have a general question about POSIX thread method:
I want to implemented absolute wait... so I wrote this method:
void wait(int msToWait)
{
pthread_mutex_lock(&count_lock);
struct timeval tv;
struct timespec toWait;
gettimeofday(&tv, NULL);
toWait.tv_sec = tv.tv_sec + msToWait/1000;
long int morenanos = (msToWait%1000)*1000000;
toWait.tv_nsec = tv.tv_usec*1000 + morenanos ;
int rc =pthread_cond_timedwait(&count_cond,&count_lock, &toWait);
if (rc != 0) {
if (EINVAL == rc) {
// I sometimes get here if the CPU is slow and toWait contains "past time".
}
....more code here
I tested it under Ubuntu gcc 4.2.4 and also Mac OS and sometimes when I wait(200) I get EINVAL error : why ? since between the time I calculated the current time and added the 200ms , that time has passed when pthread_cond_timedwait was called.
so how can one implement thread safe wait(millisec) under Unix ?
I tried in Win32 API Event and it works flawlessly. so why cant it work in unix ?
ofcourse I link with -lpthread flag.
updating:
a note : ofcourse there is no problem seen if waiting longer times (i.e. longer than 800ms ).
I am certain there is a way to do what you need to do - UNIX(es) has been around a long time. In general, the OS has control over threads and there is no guarantee that it will switch to your thread "in time". In fact, you may have a better chance of a thread being activated in time if it is doing a plain old pthread_cond_wait(). Remember, if you used pthread_cond_timedwait(), your thread could be doing something else when the other thread is trying to signal a 200ms alarm to you.
If you specify exactly what you are trying to do, maybe we can give you suggestions, perhaps without using signals in conjunction with pthreads.
If you truly need to use signals with pthreads, you have to be careful. In Butenhof's Programming with POSIX Threads, there is a whole section on using (UNIX) signals with PThreads, with plenty of caveats.
Remember that the POSIX semantics for sleeps is that the process will sleep for at least the amount of
time specified, but possibly longer, up to infinity. Making any other guarantee to the user requires
an honest-to-goodness realtime operating system.
My original intention was to imitate Java Object.wait(int) and Object.signal()
so I need to implement wait(int millisec) but I also need a mechanism to "awake" it prematurely.
usleep() and nanosleep() are all doing something similar to Pthread's wait but in order to wake them before time you need to send SIGTSTP signal . this is a process signal rather than a thread, which can cause much larger impact than i planned:
void signal()
{
pthread_mutex_lock(&count_lock);
int rc = pthread_cond_signal(&count_cond);
if (rc != 0) {
printf("problem signaling: %d ",rc);
}
pthread_mutex_unlock(&count_lock);
}