[單班計程] 程式補完計畫 特別話: volatile

看板b92902xxx作者 (Shirase Akira)時間20年前 (2004/01/07 22:27), 編輯推噓5(500)
留言5則, 5人參與, 最新討論串1/1
話說最後一次的課程在難得的準時下課下結束了, 但... 還沒結束呢... 這只是一切的開端... 各位應該還記得最後一話有一個 volatile 吧? 當時司令是將其草草帶過了, 但是事實上它會被安排在 signal 之前是有其特殊的意義的, 而且其功能就實務上常常難以取代, 所以現在來詳談 volatile. 先來談談 signal. signal 其實是有一點非常特殊的性質的, 我們來看看這份 code: -------------------------------------------------- int main(){ for(;1;){ } return 0; } -------------------------------------------------- 任何人應該都認為這是一個跑不完的程式吧? 程式的流程走進無窮的 for 迴圈, 眼前是大括號的重重包圍, 無路可逃. 但是事實上在這看似死牢的 for 中卻有一道空間的裂縫, 那就是 signal, 它可以讓你的程式流程瞬間傳送到 signal 的 handler, signal 超脫了自然的定律, 是 compiler 完全無法預期的. 接下來我們再看這一份 code: -------------------------------------------------- int a; int main(){ for(a=1;a;){ } return 0; } -------------------------------------------------- 從這份 code 我們看到了什麼? a 在進到 for 的時候被設成了 1, 然後迴圈中沒有任何一行有變動它, 所以 compiler 很有可能認為迴圈中的 a 可以不用看就知道是 1, 而將我們的 for 變成這樣: for(a=1;1;) 這樣看起來也很合理吧? 最後我們來看這一份 code: -------------------------------------------------- int a; void sighand(int signo){ printf ("Don't kill me. I'll suicide.\n"); a = 0; } int main(){ signal (2, sighand); for (a=1;a;){ } return 0; } -------------------------------------------------- 對於這份 code, compiler 也很有可能認為會動到 a 的只有 sighand, 而進入 for 之後, 再也沒有出現過 sighand, 所以認為 a 在 for 中會是定值 1, 因此而將我們的 for(a=1;a;) 變成 for(a=1;1;). 但是 compiler 錯了. 由於 signal 這個空間的裂縫, 我們可以經由 kill -2 [pid] 將程式的流程跳入 sighand, 因此 a 是定值 1 這件假設在預期外的情形被打破了, 在這裡即使我們被 kill -2, for 仍然會鐵齒地認為 a 仍然是 1, 所以不用出去, 結果該跳出的迴圈沒有跳出. 為了避免這個問題, 我們的主角 volatile 登場了. volatile 本意並不是司令所講的"禁止最佳化", 它的本意其實是用來告訴 compiler 該變數可能會產生預期外的變動, 所以不要對該變數的內容太鐵齒, 為了達成這目標的副作用就是造成許多最佳化無法進行. 所以, 上面的 code 改成以下就保證可以正確執行: -------------------------------------------------- volatile int a; void sighand(int signo){ printf ("Don't kill me. I'll suicide.\n"); a = 0; } int main(){ signal (2, sighand); for (a=1;a;){ } return 0; } -------------------------------------------------- 這個時候我們的 compiler 雖然一心認為 a 在 for 裡面應該要會是定值 1, 但是由於 volatile 的叮嚀, 最後 compiler 還是要求我們的程式每跑一圈一定要確實檢查 a, 結果我們真的抓到 sighand 偷換了 a 的值, 而能夠正常的結束迴圈. 圓滿的大結局不是嗎? ;) -- その乾いた哀愁の瞳に去來するものは何か? 失ったもの 得たもの そして廣大なネットの狹間で彼が見たものとは? 虛像と實存と記號の中に彼は今、何を想うのか? <バトルプログラマーシラセ> -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.112.30.49

推 140.112.25.181 01/07, , 1F
好文...推~
推 140.112.25.181 01/07, 1F

推140.112.171.150 01/07, , 2F
推~~~不M不行啦
推140.112.171.150 01/07, 2F

推 61.230.50.184 01/07, , 3F
推+1
推 61.230.50.184 01/07, 3F

推 140.112.25.182 01/08, , 4F
地下司令嗎???
推 140.112.25.182 01/08, 4F

推 140.112.28.27 01/08, , 5F
講的很好, 謝謝.
推 140.112.28.27 01/08, 5F
文章代碼(AID): #__1THDf (b92902xxx)