Понимание вывода программы - PullRequest
0 голосов
/ 18 февраля 2019

Я смотрел на этот вопрос обмена стека: как автоматически вызывать функцию через равные промежутки времени?

И я попытался запустить код в первом ответе

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

void timer_handler (int signum)
{
 static int count = 0;
 printf ("timer expired %d times\n", ++count);
}

int main ()
{
 struct sigaction sa;
 struct itimerval timer;

 /* Install timer_handler as the signal handler for SIGVTALRM. */
 memset (&sa, 0, sizeof (sa));
 sa.sa_handler = &timer_handler;
 sigaction (SIGVTALRM, &sa, NULL);

 /* Configure the timer to expire after 250 msec... */
 timer.it_value.tv_sec = 0;
 timer.it_value.tv_usec = 250000;
 /* ... and every 250 msec after that. */
 timer.it_interval.tv_sec = 0;
 timer.it_interval.tv_usec = 250000;
 /* Start a virtual timer. It counts down whenever this process is
   executing. */
 setitimer (ITIMER_REAL, &timer, NULL);

 /* Do busy work. */
 while (1);
}

Я не понимаю, что он делает.Похоже, что он печатает «Будильник» через 2500 миллисекунд, но я не понимаю, как это возможно, так как нет никакого оператора печати на этот счет.Как заставить его увеличивать счетчик каждые 2500 миллисекунд, как это должно быть?

1 Ответ

0 голосов
/ 18 февраля 2019

ITIMER_REAL отправляет SIGALRM не SIGVTALRM.Измените сигнал, и он будет работать.

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

void timer_handler (int signum)
{
 static int count = 0;
 printf ("timer expired %d times\n", ++count);
}

int main ()
{
 struct sigaction sa;
 struct itimerval timer;

 /* Install timer_handler as the signal handler for SIGVTALRM. */
 memset (&sa, 0, sizeof (sa));
 sa.sa_handler = &timer_handler;
 sigaction (SIGALRM, &sa, NULL);

 /* Configure the timer to expire after 250 msec... */
 timer.it_value.tv_sec = 0;
 timer.it_value.tv_usec = 250000;
 /* ... and every 250 msec after that. */
 timer.it_interval.tv_sec = 0;
 timer.it_interval.tv_usec = 250000;
 /* Start a virtual timer. It counts down whenever this process is
   executing. */
 setitimer (ITIMER_REAL, &timer, NULL);

 /* Do busy work. */
 while (1);
}

(Как правило, в обработчике сигналов плохая идея использовать printf, поскольку printf не является безопасным для асинхронного сигнала, но в вашем случае этоне должно быть опасным, потому что вы прерываете код обычного контекста, который является безопасным асинхронным сигналом (а именно, занятым циклом). Однако POSIX не гарантирует этого специального исключения, так чтоСовершенно безопасно, вы должны воздерживаться от выполнения любых небезопасных асинхронных вызовов в обработчиках сигналов и заменять printf на write(1, ...).)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...