
질문
UNIX 명령을 실행할 수 있기를 원합니다.정확하게매 초오랜 기간에 걸쳐.
명령 자체가 실행되는 데 필요한 시간 때문에 일정 시간이 지나도 뒤처지지 않는 솔루션이 필요합니다.잠,보다, 그리고 특정파이썬 스크립트이 점에 있어서는 모두 나에게 실패했습니다.
다음과 같은 마이크로 컨트롤러에서http://Arduino.cc나는 하드웨어 클럭 인터럽트를 통해 그렇게 할 것입니다. 비슷한 시간에 정확한 쉘 스크립트 솔루션이 있는지 알고 싶습니다. StackExchange.com에서 찾은 모든 솔루션은 몇 시간 이상 실행될 경우 눈에 띄는 시간 지연이 발생했습니다. 아래 세부정보를 참조하세요.
실용적인 목적/적용
nc
1초마다 (netcat)을 통해 타임스탬프를 전송하여 네트워크 연결이 계속 작동하는지 테스트하고 싶습니다 .
보내는 사람:
precise-timestamp-generator | tee netcat-sender.txt | nc $receiver $port
수화기:
nc -l -p $port > netcat-receiver.txt
완료 후 두 로그를 비교합니다.
diff netcat-sender.txt netcat-receiver.txt
차이점은 전송되지 않은 타임스탬프입니다. 이를 통해 언제 LAN/WAN/ISP에 문제가 발생하는지 알 수 있습니다.
솔루션 수면
while [ true ]; do date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done | tee timelog-sleep.txt
루프 내의 명령에도 약간의 시간이 걸리므로 시간이 지남에 따라 특정 오프셋을 가져옵니다.
정도
cat timelog-sleep.txt
2012-07-16 00:45:16
[...]
2012-07-16 10:20:36
경과 시간(초): 34520
wc -l timelog-sleep.txt
파일의 줄: 34243
정밀도 요약:
- 34520-34243 = 277 타이밍 문제
- 34520/34243 = 1.008 = 0.8% 할인
솔루션 REPEAT PYTHON
다음에서 발견:x초마다 Unix 명령을 영원히 반복합니다.
repeat.py 1 "date '+%Y-%m-%d %H:%M:%S'" >> timelog-repeat-py.txt
시간 오프셋을 피하려고 했지만 실패했습니다.
정도
wc -l timelog-repeat-py.txt
2012-07-16 13:42:44
[...]
2012-07-16 16:45:24
경과 시간(초): 10960
wc -l timelog-repeat-py.txt
파일의 줄: 10859
정밀도 요약:
- 10960-10859 = 101개의 타이밍 문제
- 10960/10859 = 1.009 = 0.9% 할인
솔루션 보기
watch -n 1 "date '+%Y-%m-%d %H:%M:%S' >> ~/Desktop/timelog-watch.txt"
정도
wc -l timelog-watch.txt
2012-07-16 11:04:08
[...]
2012-07-16 13:25:47
경과 시간(초): 8499
wc -l timelog-watch.txt
파일의 줄: 8366
정밀도 요약:
- 8499-8366 = 133개의 타이밍 문제.
- 8499/8366 = 1.016 = 1.6% 할인됩니다.
답변1
watch
매개변수를 사용해 보셨나요 --precise
?
watch -n 1 --precise "date '+%Y-%m-%d %H:%M:%S.%N' >> ~/Desktop/timelog-watch.txt"
매뉴얼 페이지에서:
일반적으로 이 간격은 한 명령 실행 완료와 다음 실행 시작 사이의 시간으로 해석됩니다. 그러나 -p 또는 --precise 옵션을 사용하면 watch가 간격 초마다 명령을 실행하도록 시도할 수 있습니다. ntptime으로 시도해보고 소수 초가 지속적으로 증가하는 일반 모드와는 대조적으로 어떻게 (거의) 동일하게 유지되는지 확인하십시오.
하지만 시스템에서 매개변수를 사용하지 못할 수도 있습니다.
또한 프로그램 실행에 1초 이상이 필요할 때 어떤 일이 발생해야 하는지 고려해야 합니다. 다음 예약된 실행을 건너뛰어야 합니까, 아니면 늦게 실행해야 합니까?
업데이트: 한동안 스크립트를 실행했는데 한 단계도 느슨해지지 않았습니다.
2561 lines
start: 2012-07-17 09:46:34.938805108
end: 2012-07-17 10:29:14.938547796
업데이트:플래그 --precise
는 데비안에 추가된 것이지만 패치는 다소 간단합니다:http://patch-tracker.debian.org/patch/series/view/procps/1:3.2.8-9squeeze1/watch_precision_time.patch
답변2
POSIXualarm()
함수를 사용하면 마이크로초 단위의 정밀도로 프로세스에 주기적으로 신호를 보내도록 커널을 예약할 수 있습니다.
간단한 프로그램을 작성해 보세요:
#include<unistd.h>
#include<signal.h>
void tick(int sig){
write(1, "\n", 1);
}
int main(){
signal(SIGALRM, tick);
ualarm(1000000, 1000000); //alarm in a second, and every second after that.
for(;;)
pause();
}
엮다
gcc -O2 tick.c -o tick
그런 다음 정기적으로 수행해야 하는 작업에 다음과 같이 연결합니다.
./tick | while read x; do
date "+%Y-%m-%d %H:%M:%S"
done | tee timelog-sleep.txt
답변3
crontab
1분의 해상도를 가지고 있습니다. 해당 분당 지연 시간이 누적되고 다음 분에 재설정되는 데 문제가 없다면 다음 기본 아이디어가 효과가 있을 수 있습니다.
* * * * * for second in $(seq 0 59); do /path/to/script.sh & sleep 1s;done
script.sh
백그라운드에서도 실행된다는 점에 유의하세요 . 이는 루프가 반복될 때마다 누적되는 지연을 최소화하는 데 도움이 됩니다.
그러나 지연이 얼마나 sleep
발생하는지에 따라 초 59가 다음 분의 초 0과 겹칠 가능성이 있습니다.
편집하다질문과 동일한 형식으로 일부 결과를 던집니다.
$ cat timelog-cron
2012-07-16 20:51:01
...
2012-07-16 22:43:00
1시간 52분 = 6720초
$ wc -l timelog-cron
6720 timelog-cron
타이밍 문제 0개, 0% 할인. 모든 시간 누적은 1분마다 재설정됩니다.
답변4
방금 작성한 Perl 스크립트는 어떻게 작동하나요?
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes qw/time sleep/;
sub launch {
return if fork;
exec @_;
die "Couldn't exec";
}
$SIG{CHLD} = 'IGNORE';
my $interval = shift;
my $start = time();
while (1) {
launch(@ARGV);
$start += $interval;
sleep $start - time();
}
사용:perl timer.pl 1 date '+%Y-%m-%d %H:%M:%S'
한 번도 건너뛰지 않고 45분 동안 실행되었으며, a) 시스템 부하가 너무 높아서 fork()가 1초 이상 걸리거나 b) 윤초가 삽입되지 않는 한 계속해서 실행될 것으로 예상됩니다.
그러나 약간의 오버헤드가 있기 때문에 명령이 정확한 초 간격으로 실행된다는 것을 보장할 수는 없지만 인터럽트 기반 솔루션보다 훨씬 나쁜지는 의심됩니다.
date +%N
(나노초, GNU 확장)을 사용하여 약 한 시간 동안 실행하고 이에 대한 몇 가지 통계를 실행했습니다. 가장 지연된 시간은 1,155마이크로초였습니다. 평균(산술 평균) 216μs, 중앙값 219μs, 표준 편차 42μs. 95%의 경우 270μs보다 빠르게 실행되었습니다. 나는 C 프로그램을 제외하고는 그것을 이길 수 없다고 생각합니다.