Почему некоторые системные вызовы защищают сигнал SIGPROF в стрейсе - PullRequest
3 голосов
/ 04 ноября 2019

Когда я связываю этот код


void printMsg();

int main() {
  signal(SIGPROF, printMsg);

  struct itimerval tick;
  memset(&tick, 0, sizeof(tick));

  tick.it_value.tv_sec = 1;  // sec
  tick.it_value.tv_usec = 0; // micro sec.
  tick.it_interval.tv_sec = 0;
  tick.it_interval.tv_usec = 0;

  setitimer(ITIMER_PROF, &tick, NULL);

  while(1) {
    ;
  }

  return 0;
}

void printMsg() {
    printf("%s","Hello World!!\n");
}

Через 1 секунду, как и ожидалось, я получаю сигнал SIGPROF

...
05:54:10 setitimer(ITIMER_PROF, {it_interval={0, 0}, it_value={1, 0}}, NULL) = 0
05:54:11 --- SIGPROF {si_signo=SIGPROF, si_code=SI_KERNEL} ---
...

Но когда я добавляю системный вызов типа write(2, "", 0) илиread(2, "", 0) in while(1) и снова strace, похоже, что SIGPROF не может быть запущено. Однако time(0) в while(1) может правильно запускать SIGPROF.

Кстати, я использую этот код для эмуляции следующего сценария PHP, который игнорирует ограничение по времени в PHP-FPM SAPI,

<?php
set_time_limit(5);  // PHP uses setitimer(ITIMER_PROF) to implement this function
while (true) {
    flush();       // PHP uses write(<fd>, "", 0) to implement this function
}

1 Ответ

1 голос
/ 04 ноября 2019

Код запускает SIGPROF с помощью ITIMER_PROF, который считает, когда выполняется процесс или когда система работает от имени процесса.

Когда процесс переходит в режим «чтения» или «записи»звонки, это не «работает». Процесс переходит в IO Wait (и система выделяет ЦП другим процессам). Когда процесс находится в IOWait, таймер не движется. Когда есть системный вызов, который выполняет обработку (в основном в системном пространстве) - например, time () представляет собой замкнутый цикл, таймер будет двигаться.

Подробнее о состояниях процесса см. В https://www.tecmint.com/linux-process-management/

Если вы хотите измерить время «часов», рассмотрите возможность использования timer_create с CLOCK_REALTIME или CLOCK_MONOTONIC

...