Итак, читая это топи c, обычным способом выхода будет использование флага. У меня вопрос, как обрабатывается ожидание? Скажем, поток должен запускаться только каждые 30 секунд, как бы вы правильно подождали эти 30 секунд?
Использование sem_timedwait () не идеально, так как зависит от системных часов и любых изменений в часы могут серьезно повлиять на ваше приложение. В этой теме c объясняется использование условных переменных. Проблема в том, что он опирается на мьютекс. Вы не можете безопасно использовать pthread_mutex_lock () и pthread_mutex_unlock () в обработчике сигналов. Итак, с точки зрения моего примера выше 30-х годов, если вы хотите выйти немедленно, кто обрабатывает мьютексную разблокировку?
Я думаю, что другой поток, единственной целью которого является проверка флага выхода, и если true, то это будет разблокировать мьютекс. Тем не менее, что это за нить? Разве это не пустая трата ресурсов, чтобы просто сидеть и постоянно проверять флаг? Не могли бы вы использовать sleep () и проверять, например, каждые 1 с?
Не думаю, что мои предположения правильные. Это кажется очень неэффективным, и я сталкиваюсь с подобным вопросом типа «как мне ждать». Я чувствую, что что-то упустил, но мой поиск приводит к темам, похожим на то, что я связал, где говорится о флагах, но ничего не ждет.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
pthread_mutex_t my_mutex;
volatile sig_atomic_t exitRequested = 0;
void signal_handler(int signum) {
exitRequested = 1;
}
bool my_timedwait(pthread_mutex_t *mutex, int seconds) {
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_t cond;
pthread_cond_init(&cond, &attr);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
ts.tv_sec += seconds;
int status = pthread_cond_timedwait(&cond, mutex, &ts);
if (status == 0) {
return false; // mutex unlocked
}
if ((status < 0) && (status != ETIMEDOUT)) {
// error, do something
return false;
}
return true; // timedout
}
void *exitThread(void *ptr) {
// constant check???
while (1) {
if (exitRequested) {
pthread_mutex_unlock(&my_mutex);
break;
}
}
}
void *myThread(void *ptr) {
while (1) {
// do work
printf("test\n");
// wait and check for exit (how?)
if (!my_timedwait(&my_mutex, 30)) {
// exiting
break;
}
}
}
int main(void) {
// init and setup signals
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
// init the mutex and lock it
pthread_mutex_init(&my_mutex, NULL);
pthread_mutex_lock(&my_mutex);
// start exit thread
pthread_t exitHandler;
pthread_create(&exitHandler, NULL, exitThread, NULL);
// start thread
pthread_t threadHandler;
pthread_create(&threadHandler, NULL, myThread, NULL);
// wait for thread to exit
pthread_join(threadHandler, NULL);
pthread_join(exitHandler, NULL);
return EXIT_SUCCESS;
}