обо всем по порядку. Введите также дополнительный код , чтобы также распечатать текущее время, вместо того, чтобы полагаться на launchd
.
Возможно, что в игру вступают различные режимы очистки для стандартного выхода.
Если стандартный вывод можно определить как интерактивное устройство (например, запускать его из командной строки), он будет строка в буфере - вы получите строку «до», очищенную перед задержкой.
В противном случае, он полностью буферизован, поэтому сброс может не произойти до тех пор, пока программа не выйдет (или вы не достигнете размера буфера (например) 4K. Это означает, что launchd
может видеть, что строки выходят вместе, оба после задержка.
Получение кода C для отметки времени в строках скажет вам, если это проблемы, что-то вроде:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while( (delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
return 0;
}
Чтобы понять, почему буферизация может быть проблемой, попробуйте запустить эту программу, как указано выше:
pax> ./testprog | while read; do echo $(date): $REPLY; done
Tue Jan 31 12:59:24 WAST 2012: 1327985961: Before delay
Tue Jan 31 12:59:24 WAST 2012: 1327985964: After delay
Вы можете видеть, что из-за буферизации обе строки появляются в цикле while
при выходе из программы , получают одинаковую метку времени 12:59:24
, несмотря на то, что они были сгенерированы за три секунды. в рамках программы.
На самом деле, если вы измените его следующим образом:
pax> ./testprog | while read; do echo $(date) $REPLY; sleep 10 ; done
Tue Jan 31 13:03:17 WAST 2012 1327986194: Before delay
Tue Jan 31 13:03:27 WAST 2012 1327986197: After delay
вы можете видеть время, которое видит «окружающая» программа (цикл while
или, в вашем случае, launchd
) полностью отключен от самой программы).
Во-вторых, usleep
- это функция, которая может давать сбой! И она может завершиться ошибкой, возвращая -1, что очень не больше нуля.
Это означает, что, если это не удастся, ваша задержка будет фактически ничем.
Одиночная спецификация UNIX , для usleep
:
При успешном завершении usleep () возвращает 0. В противном случае возвращает -1 и устанавливает errno, чтобы указать на ошибку.
Функция usleep () может завершиться ошибкой, если: [EINVAL]: интервал времени, заданный 1 000 000 или более микросекунд.
Это, безусловно, имеет место с вашим кодом, хотя было бы трудно объяснить, почему он работает после загрузки, а не до.
Интересно, что в документах Mac OSX нет EINVAL, но они do допускают EINTR, если сон прерывается извне. Итак, еще раз, кое-что вы должны проверить.
Вы можете проверить эти возможности, например:
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
int main (void) {
printf("%d: Before delay\n", time(0));
unsigned int delay = 3000000;
while( (delay=usleep(delay)) > 0);
printf("%d: After delay\n", time(0));
printf("Delay became %d, errno is %d\n", delay, errno);
}
Еще одна вещь, которую я только что заметил, из вашего кода вы, похоже, предполагаете, что usleep
возвращает количество микросекунд без ответа (оставшихся), и вы зацикливаетесь, пока все не будет сделано, но это поведение не подтверждается справочные страницы.
Я знаю, что nanosleep
делает это (обновляя переданную структуру, чтобы она содержала оставшееся время, а не возвращало его), но usleep
возвращает только 0 или -1.
Функция sleep
действует таким образом, возвращая количество секунд, которые должны пройти. Возможно, вы можете использовать эту функцию, если это возможно.
В любом случае, я все равно запустил бы этот (последний) сегмент кода выше, чтобы вы могли выяснить что фактическая проблема.