我正在研究如何用 C 撰寫一個 shell,我遇到了一種方法來使用“在實作等待命令時圍繞睡眠函式的忙回圈”。在回圈中,使用while(1)回圈。我想無條件回圈,因此占用一些處理時間和空間?忙回圈的目的究竟是什么?此外,如果惰性回圈中的唯一目標是有一個無條件回圈,那么我們不能使用任何其他形式的回圈for(;;)來代替while(1)嗎?
uj5u.com熱心網友回復:
忙回圈是故意浪費時間等待某事發生的回圈。通常,您會不惜一切代價避免繁忙回圈,因為它們會消耗 CPU 時間,無所事事,因此會浪費資源,但在極少數情況下可能需要它們。
其中一種情況確實是當您需要長時間睡眠并且您安裝了可能會中斷睡眠的信號處理程式之類的東西時。然而,“睡眠忙回圈”根本不是忙回圈,因為幾乎所有的時間都花在睡眠上。
你可以建立一個繁忙的回圈使用任何你喜歡的回圈結構,畢竟for,while,do ... while并goto給出相應的控制代碼C中的所有可互換的結構。
這是一個使用示例clock_nanosleep:
// I want to sleep for 10 seconds, but I cannot do it just with a single
// syscall as it might get interrupted, I need to continue requesting to
// sleep untill the entire 10 seconds have elapsed.
struct timespec requested = { .tv_sec = 10, .tv_nsec = 0 };
struct timespec remaining;
int err;
for (;;) {
err = clock_nanosleep(CLOCK_MONOTONIC, 0, &requested, &remaining);
if (err == 0) {
// We're done sleeping
break;
}
if (err != EINTR) {
// Some error occurred, check the value of err
// Handle err somehow
break;
}
// err == EINTR, we did not finish sleeping all the requested time
// Just keep going...
requested = remaining;
}
一個實際的繁忙回圈看起來像下面這樣,其中var據說是由其他人(例如另一個執行緒)設定的某種原子變數:
while (var != 1);
// or equivalent
while (1) {
if (var == 1)
break;
}
不用說,這是您想要避免的那種回圈,因為它會不斷檢查浪費 CPU 的情況。更好的實作是使用信號、pthread 條件變數、信號量等。通常有很多不同的方法可以避免忙回圈。
最后,請注意,在上述情況下,正如@einpoklum在評論中所說,編譯器可能會通過放棄檢查來“優化”整個回圈體var,除非它知道它可能會改變。一個volatile限定詞可以幫助,但它確實取決于具體的方案,不要拿上面的代碼比一個愚蠢的例子以外的任何其他。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/351552.html
上一篇:如何在bash中修剪字串變數
