Since nobody anwser my last post titled “pthread_mutex_timedlock base on the
CLOCK_MONOTONIC”. Here my test program showing that pthread_muxtex_timedlock
is affected by change of the real time clock even if the CLOCK_MONOTONIC is
used. The semaphore should be block for one nimute, but the main thread
forward the time by 1 hour, the semaphore unblock immediately. Can soneone
comment on it and suggest a way to have a mutex not affected by the change
of the real time clock.
Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
// Thread that creates and locks on a semaphore
void* ThreadSemaphoreLock(void * ptr)
{
timespec timeout;
timespec timeStart;
timespec timeEnd;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t attr;
int rc;
clock_gettime( CLOCK_REALTIME, &timeStart );
clock_gettime( CLOCK_MONOTONIC, &timeout );
timeout.tv_sec += 60; // Timeout in 60 seconds
timeout.tv_nsec = 0;
// Initializes the semaphore
pthread_mutex_init(&mutex,&attr );
// Try to lock the semaphore with a timeout value of 60 seconds
pthread_mutex_timedlock( &mutex, &timeout );
clock_gettime( CLOCK_REALTIME, &timeEnd );
printf(“The sem_timedwait timeout elapsed after %lf seconds\n”,
(( timeEnd.tv_sec - timeStart.tv_sec ) +
(double)( timeEnd.tv_nsec - timeStart.tv_nsec ) / (double)1000000000L) );
return NULL;
}
int main(int argc, char *argv)
{
struct timespec currTime;
pthread_attr_t attrThread;
pthread_t thread;
int rc;
// Creates and starts a thread
pthread_attr_init( &attrThread );
pthread_attr_setdetachstate( &attrThread, PTHREAD_CREATE_JOINABLE );
pthread_create( &thread, &attrThread, &ThreadSemaphoreLock, NULL);
// Wait for the thread to create and initialize
sleep(3);
// Changes the system time
clock_gettime(CLOCK_REALTIME, &currTime);
// Add 1 hour to current time
currTime.tv_sec += 3600;
currTime.tv_nsec = 0;
clock_settime(CLOCK_REALTIME, &currTime);
// Wait for the thread to finish
assert(pthread_join(thread,NULL)==0);;
// Set the time back to what it was
currTime.tv_sec -= 3600;
currTime.tv_nsec = 0;
clock_settime(CLOCK_REALTIME, &currTime);
return 0;
}