void wait(int timeInMs)
{
struct timespec timeToWait;
timeToWait.tv_sec = 5;
timeToWait.tv_nsec = timeInMs*1000;
int rt;
pthread_mutex_lock(&am
That code doesn't sleep, it checks a condition for a while. As you are not probably setting cond ok it just returns immediately.
If you are not willing to synchronize threads around a signal then pthread_cond _wait is not what you need. Check here how condition variables work.
if you want to sleep with seconds precision use sleep
If you want to sleep with microseconds precision use select with timevals.
Considering you are using timespec, and your goal isn't to synchronize but to wait I'd suggest nanosleep.
#include <time.h>
.
.
.
struct timespec remain;
remain.tv_sec = 5;
remain.tv_nsec = timeInMs * 1000;
do {
if ( nanosleep( &remain, &remain ) == 0 || errno != EINTR ) {
break;
}
} while ( 1 );
.
.
.
pthread_cond_timedwait uses absolute time, so need to:
timeInMs is millisecond: 1 millisecond = 1000 microseconds = 1000 * 1000 nanoseconds.
void wait(int timeInMs)
{
struct timeval tv;
struct timespec ts;
gettimeofday(&tv, NULL);
ts.tv_sec = time(NULL) + timeInMs / 1000;
ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeInMs % 1000);
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= (1000 * 1000 * 1000);
int n = pthread_cond_timedwait(&condition, &mutex, &ts);
if (n == 0)
// TODO: singaled
else if (n == ETIMEDOUT)
// TODO: Time out.
}
Using any variant of sleep, the behavior is not guaranteed. All the threads can also sleep since the kernel is not aware of the different threads.
A safer and cleaner solution to use is pthread_cond_timedwait
. You used the API incorrectly. Here is a better example:
pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
void mywait(int timeInMs)
{
struct timespec timeToWait;
struct timeval now;
int rt;
gettimeofday(&now,NULL);
timeToWait.tv_sec = now.tv_sec+5;
timeToWait.tv_nsec = (now.tv_usec+1000UL*timeInMs)*1000UL;
pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
printf("\nDone\n");
}
void* fun(void* arg)
{
printf("\nIn thread\n");
mywait(1000);
}
int main()
{
pthread_t thread;
void *ret;
pthread_create(&thread, NULL, fun, NULL);
pthread_join(thread,&ret);
}
You need to specify how much time to wait from current time. Since you were only telling 5 sec and some nano-seconds it found that the time had already passed and did not wait...Please let me know if any more doubts.
Main reference: http://pubs.opengroup.org/onlinepubs/009695299/functions/pthread_cond_timedwait.html
FIX of the code of andrewrk above
I can confirm Adrian May that gettimeofday doesn't function correctly! The code behavior of andrewrk inside an infinite thread like this
static void * thread_infinite(void * unused) {
while (1) {
// compute stuff
mywait(5);
}
is unpredictable: it runs approximate 700 times more until it blocks!
The correct version of the code of andrewrk is:
pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
void mywait(int timeInS)
{
struct timespec ts;
struct timeval now;
int rt = 0;
// gettimeofday(&now,NULL); // DOES NOT FUNCTION CORRECTLY
// timeToWait.tv_sec = now.tv_sec+5;
// timeToWait.tv_nsec = (now.tv_usec+1000UL*timeInMs)*1000UL;
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += timeInS;
pthread_mutex_lock(&fakeMutex);
do {
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &ts);
}
while (rt == 0);
pthread_mutex_unlock(&fakeMutex);
}
The pthread_cond_timedwait
function takes an absolute time, not a relative time. It takes the time you want to stop waiting, not how long you want to wait.