잠깐 동안 잠을 자려면 루프가 필요합니다


14

내 컴퓨터에서 1 초의 간단한 명령을 반복하는 사이클을 실행해야합니다.

내가 필요하다고 가정 해 봅시다.

  • 증가하는 enumaration (file-0, file-1, file-2, ...)으로 파일을 저장하려면이 예제에서 사소한 것으로 생성하십시오. time > file-$x
  • 나는 이것을 1/70 초마다 (예를 들어) 매분의 일 초로 표현하고 싶기 때문에 이것을해야합니다.

어떻게 정확하게 정확하고 bash 스크립트로 모든 것을 표현할 수 있습니까?

분수는 결정할 수없는 양을 생성 할 수 있으므로 정확해야하며 최소 4-5 자릿수가 필요합니다.

답변:


12

bash에서 분수에서 소수로 변환하려면 다음과 같이하십시오.

myvar=$(echo "scale=4; 5/10" | bc)

그런 다음 해당 값을 반복하려면

for i in $(seq 1 1000); do sleep $myvar; done

데비안 (GNU)에서 수면 구현은 십진수 수면 값을 허용하는 것 같습니다.

운수 나쁘게..

이런 종류의 정밀도 (소수점 4-5 자리)를 사용하면 펄 스크립트 나 컴파일 된 프로그램과 같은 것을 원할 것입니다. 루프 내에서 프로그램을 호출하는 오버 헤드로 인해 많은 지터가 발생합니다. 수면 자체를 호출하는 데 몇 밀리 초가 걸립니다.

1000 회 수행 된 1 / 10,000 초의 다음 수면을 고려하십시오.

time for i in $(seq 1 1000); do sleep 0.0001; done

real    0m2.099s
user    0m3.080s
sys     0m1.464s

예상 결과는 1/10 초입니다. 수면은 원하는 공차 근처에 없습니다.

/programming/896904/how-do-i-sleep-for-a-millisecond-in-perl

펄의 Time :: HiRes, 1000 * 1000 마이크로 초 사용 :

my $i=0;
for($i=0;$i<=1000;$i++) {
        usleep(1000);
}

real    0m1.133s
user    0m0.024s
sys     0m0.012s

우리에게 1 초에 훨씬 더 가까이 다가갑니다.


4-5 소수를 달성 할 수 없다면 대안으로 최상의 결과를 얻을 것이지만 내 요점은 소수 또는 초가 아닌 분수로 표현해야한다는 것입니다.
user1717079

bash를 포함한 모든 스크립팅 언어에서 분수를 소수로 변환하는 것은 전혀 사소한 일입니다. 예 : echo "scale = 4; 5/10"| bc
Rob Bos

이제 표현을 변환하는 방법을 얻었습니다. 이제 문제는 간단한 배쉬가 실제로
느리고이

예, 약 1/10 초보다 훨씬 더 정확한 것을 원한다면 프로그램이 루프 내에서 오버 헤드를 호출하지 않도록 펄이나 파이썬을 원할 것입니다.
Rob Bos

7

어쩌면 당신은 단순히 실행할 수 있습니다

sleep 0.7

?

man 1 sleep

archlinux배포판에서 :

DESCRIPTION NUMBER 초 동안 일시 중지합니다. SUFFIX는 's'(초) (기본값), 'm'(분), 'h'(시간) 또는 'd'(일) 일 수 있습니다. NUMBER가 정수가 필요한 대부분의 구현과 달리 여기서 NUMBER는 임의의 부동 소수점 수일 수 있습니다. 두 개 이상의 인수가 제공되면 해당 값의 합계로 지정된 시간 동안 일시 중지하십시오.


sleep분수 허용? 가짜 루프로 완전한 예제를 제공 할 수 있습니까?
user1717079

0.7 내 문제를 나타내는 것은 분수가 아닙니다 ... 내 문제는 세분성에 관한 것입니다. 1/3 정도를 생각하고 수면을 정확하게하십시오.
user1717079

6

프로세스를 생성하고 새 실행 파일을로드하는 데 몇 밀리 초가 걸리므로 정밀도가 실제로는 맞지 않습니다. 또한 많은 시스템의 CPU 시간은 최대 10ms의 슬라이스로 프로세스에 할당됩니다.

그러나 일부 sleep구현에는 소수의 초가 걸리며 zsh와 ksh93은 모두 $SECONDS특수 변수를로 소수로 만들 수 있습니다 typeset -F SECONDS.

예 (zsh) :

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do sleep $((1./70)); date +%s.%N; done | { head -n3;echo ..;tail -n3; }; echo $SECONDS
1350076317.374870501
1350076317.391034397
1350076317.407278461
..
1350076318.464585550
1350076318.480887660
1350076318.497133050
1.1393780000

죄송합니다. 다음을 기준으로 수면 시간을 조정할 수 있습니다 $SECONDS.

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do sleep $((i/70. - SECONDS)); date +%s.%N; done | { head -n3;echo ...;tail -n3; }; echo $SECONDS
1350076420.262775654
1350076420.277012997
1350076420.291302750
../..
1350076421.219682227
1350076421.234134663
1350076421.248255685
1.0020580000

이 2 밀리 초는 아마도 마지막 sleepdate명령 을 실행하는 것으로 설명 될 것입니다 .

또한 zsh에는 zselect100 분의 1 초로 표시되는 제한 시간 이 내장되어 있습니다. ksh93은 sleep내장되어 있으며 부동 소수점을 허용하며 printf날짜 / 시간을 인쇄 할 수 있습니다.

$ typeset -F SECONDS=0; for ((i=1; i<=70; i++)); do ((i<4 || i>67)) && printf '%(%S.%N)T\n' now; sleep $((i/70.-SECONDS)); done; echo $SECONDS
20.823349000
20.837510000
20.851663000
21.780099000
21.794254000
21.808405000
0.9992358685

당신이 더 정확한 무엇을 원하는 경우에, 당신은 아마 실시간 기능이있는 실시간 운영 체제 또는 운영 체제를 할 것입니다 확실 하지 쉘을 사용합니다.


sleep 1/70내 컴퓨터에서 허용되지 않습니다 ...
user1717079

내가 달성하고 싶은 것에 가깝지 않고 어떻게 물건을 더 빨리 실행할 수 있습니까?
user1717079

유감스럽게도, 분수로, n과 m이 정수인 경우 n / m으로 표현되는 것이 아니라 소수 부분을 가진 소수로 표현했습니다. 나는 적절한 영어 용어에 대해 확신이 없지만 십진 부동 소수점 숫자 라고 부를 수 있다고 가정합니다.
Stéphane Chazelas

나는 ... 쉘의를 피하기 위해거야라고 생각
user1717079

대답이 맞습니다. 쉘과 프로세스는 일반적으로 밀리 초 해상도에 적합하지 않습니다. 안정적인 성능을 위해서는 usleep (3) 등을 호출하는 프로그램을 컴파일해야합니다. 커널을 다른 구성으로 다시 컴파일해야 할 수도 있습니다. 최소한 커널의 런타임 스케줄러에 다른 매개 변수를 제공하십시오. 이것은 쉬운 일이 아닙니다. 표준 커널을 사용한 표준 데비안 설치에는 실시간 기능이 제한되어 있습니다. 그래도 nice (1) 명령을 확인하고 싶을 수도 있습니다. 도움이 될 수 있습니다.
thb

3

쉘이 sleep분수를 받아들이지 않으면 perl을 사용하십시오.

sleep_fraction() {
  /usr/bin/perl -e "select(undef, undef, undef, $1)"
}

sleep_fraction 0.01428

분수를 찾아야하는 경우 echo "scale=5; 1/70" | bc


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.