질문

질문

질문

UNIX 명령을 실행할 수 있기를 원합니다.정확하게매 초오랜 기간에 걸쳐.

명령 자체가 실행되는 데 필요한 시간 때문에 일정 시간이 지나도 뒤처지지 않는 솔루션이 필요합니다.,보다, 그리고 특정파이썬 스크립트이 점에 있어서는 모두 나에게 실패했습니다.

다음과 같은 마이크로 컨트롤러에서http://Arduino.cc나는 하드웨어 클럭 인터럽트를 통해 그렇게 할 것입니다. 비슷한 시간에 정확한 쉘 스크립트 솔루션이 있는지 알고 싶습니다. StackExchange.com에서 찾은 모든 솔루션은 몇 시간 이상 실행될 경우 눈에 띄는 시간 지연이 발생했습니다. 아래 세부정보를 참조하세요.

실용적인 목적/적용

nc1초마다 (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

crontab1분의 해상도를 가지고 있습니다. 해당 분당 지연 시간이 누적되고 다음 분에 재설정되는 데 문제가 없다면 다음 기본 아이디어가 효과가 있을 수 있습니다.

* * * * * 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 프로그램을 제외하고는 그것을 이길 수 없다고 생각합니다.

관련 정보