Сборщик мусора использует несколько сигналов (Согласно документации по отладке , SIGSEGV
, SIGBUS
, а также SIGPWR
и SIGXCPU
в многопоточных linux установках, подобных вам " используется внутренне) и устанавливает для них функции обработчика сигнала.
sleep()
будет прерван при вызове обработчика сигнала и возвращает количество секунд, оставшихся до истечения времени ожидания, если оно не прервано. Это произойдет, если сборка будет запущена в середине сна.
Итак, если вы хотите смешать sleep()
с сборщиком мусора, вам придется использовать al oop, например:
int timeout = 100;
int time_remaining;
while ((time_remaining = sleep(timeout)) > 0) {
timeout = time_remaining;
}
Более надежная реализация использует nanosleep()
напрямую (это то, как sleep()
реализовано в Linux + Glib c) для лучшей обработки ошибок:
struct timespec req = { .tv_sec = 100, .tv_nsec = 0 };
struct timespec rem;
while (nanosleep(&req, &rem) < 0) {
if (errno == EINTR) {
// Interrupted by a signal handler
req = rem;
} else {
// Some other error happened; handle appropriately for your application
perror("nanosleep");
exit(EXIT_FAILURE);
}
}
Еще более надежная версия, которая не будет спать дольше 100 секунд из-за времени, используемого сборщиком мусора (если только время, проведенное до этого времени в спящем режиме + g c превышает это время), использует clock_nanosleep()
спать до истечения заданной отметки времени:
struct timespec req;
if (clock_gettime(CLOCK_MONOTONIC, &req) < 0) {
perror("clock_gettime");
exit(EXIT_FAILURE);
}
req.tv_sec += 100;
int rc;
while ((rc = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &req, NULL)) != 0) {
if (rc != EINTR) {
fprintf(stderr, "clock_nanosleep: %s\n", strerror(rc));
exit(EXIT_FAILURE);
}
}