ต้องการวนรอบการนอนหลับเป็นเสี้ยววินาที


14

ในเครื่องของฉันฉันต้องดำเนินการรอบที่วนซ้ำ 1 คำสั่งง่ายๆที่จะต้องมีความล่าช้าแสดงในเสี้ยววินาที

สมมติว่าฉันต้องการ:

  • เพื่อบันทึกไฟล์ด้วย enumaration ที่เพิ่มขึ้น (file-0, file-1, file-2, ... ) สร้างโดยสิ่งเล็กน้อยสำหรับตัวอย่างนี้เช่น time > file-$x
  • ฉันต้องทำเช่นนี้ทุกๆ 1/70 ของวินาที (เป็นตัวอย่าง) เพราะฉันต้องการแสดงเวลาของฉันด้วยเศษส่วนของวินาที

ฉันจะแม่นยำและมีทุกอย่างแสดงออกด้วยสคริปต์ทุบตีได้อย่างไร

เศษส่วนสามารถสร้างปริมาณที่กำหนดไม่ได้ฉันต้องแม่นยำและต้องมีทศนิยมอย่างน้อย 4-5 ตำแหน่ง

คำตอบ:


12

ในการแปลงจากเศษส่วนเป็นทศนิยมโดยใช้ bash ให้ทำดังนี้

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

จากนั้นเมื่อต้องการวนรอบค่านั้น

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

การนำ sleep ไปใช้ของฉันใน Debian (GNU) ดูเหมือนจะยอมรับค่า sleep sleep

น่าเสียดาย..

ด้วยความแม่นยำ (ทศนิยม 4-5 ตำแหน่ง) คุณจะต้องการบางอย่างเช่นสคริปต์ Perl หรือโปรแกรมที่คอมไพล์ ค่าใช้จ่ายในการโทรโปรแกรมใด ๆ ภายในลูปจะเพิ่มความกระวนกระวายใจเป็นจำนวนมาก การโทรไปที่สลีปจะใช้เวลาไม่กี่มิลลิวินาที

ลองพิจารณาสิ่งต่อไปนี้ 1 ใน 10,000 ของการนอนหลับครั้งที่สองทำ 1,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

ใช้เวลาของ perl :: HiRes, 1,000 * 1,000 microseconds:

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

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

ให้เราเข้าใกล้วินาทีมากขึ้น


ถ้ามันเป็นไปไม่ได้ที่จะได้ 4-5 ทศนิยมฉันจะได้ผลลัพธ์ที่ดีที่สุดเท่าที่จะเป็นไปได้ แต่จุดของฉันคือฉันต้องแสดงมันเป็นเศษส่วนไม่ใช่ทศนิยมหรือวินาที
user1717079

การแปลงเศษส่วนเป็นทศนิยมในภาษาสคริปต์ใด ๆ รวมถึงการทุบตีนั้นน่าสนใจเล็กน้อย เช่น echo "scale = 4; 5/10" | bc
Rob Bos

ตอนนี้ฉันมีวิธีแปลงนิพจน์ปัญหาตอนนี้ก็คือทุบตีง่าย ๆ มันช้ามากและไม่ทันกับความถี่นี้ ...
user1717079

ใช่ถ้าคุณต้องการอะไรที่แม่นยำกว่าประมาณ 1 ใน 10 ของวินาทีคุณอาจต้องการ perl หรือ python เพื่อหลีกเลี่ยงโปรแกรมที่เรียกโอเวอร์เฮดภายในลูป
Rob Bos

7

บางทีคุณสามารถเรียกใช้

sleep 0.7

?

man 1 sleep

บนarchlinuxdistro ของฉัน:

DESCRIPTION หยุดชั่วคราวเป็น NUMBER วินาที SUFFIX อาจเป็น 'วินาที' สำหรับวินาที (ค่าเริ่มต้น), 'm' สำหรับนาที, 'h' สำหรับชั่วโมงหรือ 'd' สำหรับวัน แตกต่างจากการใช้งานส่วนใหญ่ที่ต้องการ NUMBER เป็นจำนวนเต็มที่นี่ NUMBER อาจเป็นเลขทศนิยมโดยพลการ รับอาร์กิวเมนต์สองตัวขึ้นไปหยุดชั่วคราวตามระยะเวลาที่ระบุโดยผลรวมของค่า


sleepอนุญาตให้มีเศษส่วนหรือไม่ คุณสามารถเสนอตัวอย่างที่สมบูรณ์แบบด้วยลูปปลอมได้ไหม
user1717079

0.7 ไม่ใช่เศษส่วนที่แสดงออกถึงปัญหาของฉัน ... ปัญหาของฉันเกี่ยวกับการละเอียด คิดว่าประมาณ 1/3 แล้วพยายามนอนให้ถูกต้อง
user1717079

6

การวางกระบวนการและโหลดไฟล์ปฏิบัติการใหม่ในนั้นมีแนวโน้มที่จะใช้เวลาสักครู่เพื่อความแม่นยำแบบนั้นไม่สมเหตุสมผล นอกจากนี้โปรดทราบว่าเวลา CPU ในหลาย ๆ ระบบจะถูกจัดสรรให้กับกระบวนการโดยแบ่งเป็น 10ms

ต้องบอกว่าบางsleepการใช้งานใช้ตัวเลขเศษส่วนของวินาทีและทั้งสอง zsh และ ksh93 สามารถทำให้พวกเขาเป็นเศษส่วนตัวแปรพิเศษกับ$SECONDStypeset -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

miliseconds 2 พิเศษเหล่านั้นอาจถูกนำมาใช้เพื่อเรียกใช้งานล่าสุดsleepและdateคำสั่ง

นอกจากนี้โปรดทราบว่า zsh มีzselectbuiltin พร้อมหมดเวลาที่แสดงในร้อยของวินาที และ 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) หรือที่คล้ายกัน - และคุณอาจต้องคอมไพล์เคอร์เนลของคุณใหม่ด้วยการกำหนดค่าที่แตกต่างกันเช่นกัน หรืออย่างน้อยฟีดพารามิเตอร์ที่แตกต่างกับตัวจัดกำหนดการรันไทม์ของเคอร์เนลของคุณ นี่เป็นสิ่งที่ไม่ควรทำ การติดตั้ง Debian มาตรฐานพร้อมเคอร์เนลมาตรฐานมีความสามารถแบบเรียลไทม์ จำกัด ยังคุณอาจต้องการตรวจสอบคำสั่ง nice (1); มันอาจช่วยได้
บาท

3

ถ้าเปลือกของคุณsleepไม่ยอมรับเศษส่วนให้ใช้ Perl

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

sleep_fraction 0.01428

หากคุณต้องการหาเศษส่วนให้ใช้ echo "scale=5; 1/70" | bc


0

ภายใต้Alpine Linux (Busybox) คุณสามารถวนซ้ำเป็นไมโครวินาทีด้วยusleep 10(เทียบเท่ากับ0.00001หนึ่งวินาที)

GNU sleep รองรับเศษส่วนของวินาที: sleep 0.00001

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.