Вызов pthread_cond_timedwait не работает с механизмом блокировки мьютекса
У меня есть приложение для входа. В котором по истечении определенного времени (настраиваемое пользователем время) мне нужно закрыть текущий файл журнала, создать новый файл журнала и записать данные.
В моей программе есть 2 критических раздела кода.
- Запись данных в файл (в
while(1)
) - Закройте и откройте новый файл
Всякий раз, когда истекает время, мне нужно остановить запись в файл и закрыть его, открыть новый файл журнала и начать запись.
Для этого я создал пример приложения точно так же, как мое приложение, но вместо файловой операции здесь я делаю с printf
,
я использую pthread_cond_timedwait
вызов для обработки операции, связанной с таймером. Вот мой пример кода -
#include <stdio.h>
#include <sys/time.h>
#include <errno.h>
#include <pthread.h>
/* For safe condition variable usage, must use a boolean predicate and */
/* a mutex with the condition. */
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
#define WAIT_TIME_SECONDS 10
void *threadfunc(void *parm)
{
int rc;
struct timespec abstime;
struct timeval now;
/* Usually worker threads will loop on these operations */
while (1) {
rc = gettimeofday(&now, NULL);
/* Convert from timeval to timespec */
abstime.tv_sec = now.tv_sec + WAIT_TIME_SECONDS;
abstime.tv_nsec = (now.tv_usec + 1000UL * WAIT_TIME_SECONDS) * 1000UL;
abstime.tv_sec += abstime.tv_nsec / (1000 * 1000 * 1000);
abstime.tv_nsec %= (1000 * 1000 * 1000);
printf("Thread blocked\n");
pthread_mutex_lock(&mutex);
rc = pthread_cond_timedwait(&cond, &mutex, &abstime);
pthread_mutex_unlock(&mutex);
printf("Wait timed out!\n");
/* critical section of code */
pthread_mutex_lock(&lock);
printf("Thread consumes work here\n");
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(int argc, char **argv)
{
int rc=0;
pthread_t threadid;
rc = pthread_create(&threadid, NULL, threadfunc, NULL);
if (rc != 0) {
printf("Thread creation failed err:%d\n", errno);
return -1;
}
while (1) {
/* critical section of code */
sleep(1);
pthread_mutex_lock(&lock);
printf("One work item to give to a thread\n");
pthread_mutex_unlock(&lock);
}
printf("Wait for threads and cleanup\n");
pthread_join(threadid, NULL);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
printf("Main completed\n");
return 0;
}
Этот код не работает. Всякий раз, когда pthread_cond_timedwait
истекает threadfunc
функция должна получить мьютекс lock
и это нужно распечатать заявления. После печати отпускаю мьютекс. Но этого не происходит. Контроль никогда не передается от main()
в threadfunc
, Что здесь происходит не так?
Но вместо мьютекса, если я использую переменную для обработки критической части кода, я могу это сделать. Сказать -
static int stop = 0; // take a global variable
//inside threadfunc
/* critical section of code */
stop = 1; //Replace pthread_mutex_lock with this
printf("Thread consumes work here\n");
stop = 0; //Replace pthread_mutex_unlock with this
//in main()
while (1) {
/* critical section of code */
sleep(1);
if (!stop)
printf("One work item to give to a thread\n");
}
Этот подход работает нормально.
Когда я использую более одного мьютекса в моем коде, я не могу это реализовать. Что на самом деле происходит позади? Я что-то упускаю, когда использую мьютекс для обработки критической части кода?
Заранее спасибо!