#inlcude unsigned int alarm(unsigned int seconds);
int pause(void);
alarm是乙個鬧鐘,在指定的秒數之後發出乙個sigalrm訊號;
但是,alarm函式自身是馬上就返回的,不用等待n秒之後再返回,非同步;
這個訊號只能本程序自己接收;
如果在呼叫alarm時,前乙個鬧鐘還沒到觸發訊號的時候,則返回該鬧鐘的剩餘時間,同時用新鬧鐘的時間替換舊鬧鐘的剩餘時間;
如果前面沒有鬧鐘,返回0;
alarm(0)表示取消以前未觸發的鬧鐘,返回舊鬧鐘的剩餘時間,不會發出sifalrm訊號;
pause使得本程序掛起,直到捕捉到任意乙個訊號;
只有執行了乙個訊號處理程式,並從其返回時,pause才返回;返回值-1;
我們用上面兩個函式就能自己實現乙個sleep的功能。如下:
#include #include #include #include #include void sig_alrm(int signo);
unsigned int sleep1(unsigned int seconds);
int main()
// 10.10 sleep的實現1
void sig_alrm(int signo)
unsigned int sleep1(unsigned int seconds)
//2, 定好鬧鐘傳送訊號
alarm(seconds);
//3,等待訊號
pause();
//4,清除鬧鐘
return(alarm(0));
}
呼叫alarm可以等待指定時間後觸發訊號,呼叫pause可以一直等待訊號的出現。這兩個一結合就是sleep的功能。
實現效果如下:
➜ code ./study_linux
wait for 3s
recived sigalrm
end
但是,這個sleep的實現是有一些問題的:
我們這裡用alarm來發訊號,但是我們沒有考慮到會不會在呼叫sleep1之前剛好有乙個未觸發的鬧鐘?如果有的話,那麼我們會把別人的鬧鐘清除掉;
我們註冊了sigalrm,為它指定了乙個處理程式,所以也就修改了原先的配置,或許人家原先是忽略這個訊號或者使用預設值呢。那麼我們在sleep結束前是不是應當恢復這些配置?
alarm與pause之間有乙個競爭關係。如果執行玩alarm之後,進入了子程序,而不是馬上呼叫pause,那麼就有可能在執行了sigalrm的處理程式之後才呼叫pause,這樣會造成pause一直不被喚醒。。。
現在我們用setjmp來解決第三種問題。
利用setjmp和longjmp可以實現在不同的函式間跳轉。這是goto實現不了的功能。goto只能在函式內部跳轉。
#include #include #include #include #include #include static jmp_buf env_alrm; //儲存setjmp時的環境
unsigned int sleep2(unsigned int seconds);
int main()
//sleep的第二種實現
void sig_alrm2(int signo)
unsigned int sleep2(unsigned int seconds)
//等於0表示第一次執行
//等於1表示sig_alrm2已經被觸發了,再返回這裡
if (setjmp(env_alrm) == 0)
//4,清除鬧鐘
return(alarm(0));
}
現在我們看看,就算在執行alarm之後由於某個原因,沒有馬上執行pause,等待n秒之後,觸發了訊號會怎麼樣?
這時執行了sig_alrm2,執行longjmp時,跳回到setjmp,並使得setjmp返回1,判斷失敗,於是return。
所以即便pause沒有執行也不會出錯。
從標準輸入讀字元,如果到了限制的時間read還沒有完成的話,就停止讀取
我們可以在讀取前設定鬧鐘,讀取後取消鬧鐘;對大部分系統而言,一旦收到訊號並進行處理,則read這種慢系統呼叫就會被終止。所以如果超過了時間read就算沒有返回也會被動終止。
**如下:
#include #include #include #include #include #include #define maxline 1024
int main()
//設定鬧鐘
alarm(20);
//從標準輸入讀取
//對大部分系統而言,捕獲到訊號並處理時,會使得read操作終止
if ((n = read(stdin_fileno,line,maxline)) < 0)
//如果讀完一行之後,鬧鐘還沒觸發,則取消鬧鐘
alarm(0);
//將讀取的內容列印到螢幕上
printf("write: \n");
write(stdout_fileno, line, n);
exit(0);
}
可惜的是,對於ubuntu而言,捕獲訊號並不會使得read終止,而是會使得其重啟。。。。 linux學習筆記17
vim vim介紹 vim是vi的公升級版,vim和vi的最大區別就是編輯乙個文字時vi不會顯示顏色,vim會顯示顏色,vim的安裝方法yum install y vim enhanced。vim顏色顯示 vim的顏色和你檔案的具體內容有關,相同的檔案在不同的目錄下都有可能導致顏色不存在,vim的配...
linux指令碼攻略學習筆記17
sed是進行文字替換的不二之選。這樣,我們就可以通過sed用空白替代匹配的句子。先建立乙個包含替換文字的檔案。例如 我們的目標是移除包含 mobile phones 的句子。可以用sed語句來實現 這裡的匹配模式是用來匹配整句文字的正規表示式,檔案中的每一句話第乙個字元都是空格,句與句之間用 來分割...
linux學習筆記17 管好網路
網路介面 network inte ce ifconfig 所有使用者都可以用此命令檢視網路介面,但是只有root使用者才可以操縱網路介面 此講中所有網路都是指的乙太網 stu localhost ifconfig eth0 link encap ethernet hwaddr 00 0c 29 5...