linux程式控制-wait()
http://blog.chinaunix.net/u1/53053/showart_425197.html
#include <sys/types.h> /* 提供型別pid_t的定義 */
|
引數status用來儲存被收集程式退出時的一些狀態,它是一個指向int型別的指標。但如果我們對這個子程式是如何死掉的毫不在意,只想把這個殭屍程式消滅掉,(事實上絕大多數情況下,我們都會這樣想),我們就可以設定這個引數為NULL,就象下面這樣:
pid = wait(NULL);
|
/* wait1.c */
|
編譯並執行:
$ cc wait1.c -o wait1
|
如果引數status的值不是NULL,wait就會把子程式退出時的狀態取出並存入其中,這是一個整數值(int),指出了子程式是正常退出還是被非正常結束的(一個程式也可以被其他程式用訊號結束,我們將在以後的文章中介紹),以及正常結束時的返回值,或被哪一個訊號結束的等資訊。由於這些資訊被存放在一個整數的不同二進位制位中,所以用常規的方法讀取會非常麻煩,人們就設計了一套專門的巨集(macro)來完成這項工作,下面我們來學習一下其中最常用的兩個:
1,WIFEXITED(status) 這個巨集用來指出子程式是否為正常退出的,如果是,它會返回一個非零值。
(請注意,雖然名字一樣,這裡的引數status並不同於wait唯一的引數--指向整數的指標status,而是那個指標所指向的整數,切記不要搞混了。)
2, WEXITSTATUS(status) 當WIFEXITED返回非零值時,我們可以用這個巨集來提取子程式的返回值,如果子程式呼叫exit(5)退出,WEXITSTATUS(status) 就會返回5;如果子程式呼叫exit(7),WEXITSTATUS(status)就會返回7。請注意,如果程式不是正常退出的,也就是說, WIFEXITED返回0,這個值就毫無意義。
下面通過例子來實戰一下我們剛剛學到的內容:
/* wait2.c */
|
$ cc wait2.c -o wait2
|
當然,處理程式退出狀態的巨集並不止這兩個,但它們當中的絕大部分在平時的程式設計中很少用到,就也不在這裡浪費篇幅介紹了,有興趣的讀者可以自己參閱Linux man pages去了解它們的用法。
有時候,父程式要求子程式的運算結果進行下一步的運算,或者子程式的功能是為父程式提供了下一步執行的先決條件(如:子程式建立檔案,而父程式寫入資料),此時父程式就必須在某一個位置停下來,等待子程式執行結束,而如果父程式不等待而直接執行下去的話,可以想見,會出現極大的混亂。這種情況稱為程式之間的同步,更準確地說,這是程式同步的一種特例。程式同步就是要協調好2個以上的程式,使之以安排好地次序依次執行。解決程式同步問題有更通用的方法,我們將在以後介紹,但對於我們假設的這種情況,則完全可以用wait系統呼叫簡單的予以解決。請看下面這段程式:
#include <sys/types.h>
|
waitpid系統呼叫在Linux函式庫中的原型是:
#include <sys/types.h> /* 提供型別pid_t的定義 */
|
從引數的名字pid和型別pid_t中就可以看出,這裡需要的是一個程式ID。但當pid取不同的值時,在這裡有不同的意義。
- pid>0時,只等待程式ID等於pid的子程式,不管其它已經有多少子程式執行結束退出了,只要指定的子程式還沒有結束,waitpid就會一直等下去。
- pid=-1時,等待任何一個子程式退出,沒有任何限制,此時waitpid和wait的作用一模一樣。
- pid=0時,等待同一個程式組中的任何子程式,如果子程式已經加入了別的程式組,waitpid不會對它做任何理睬。
- pid<-1時,等待一個指定程式組中的任何子程式,這個程式組的ID等於pid的絕對值。
options提供了一些額外的選項來控制waitpid,目前在Linux中只支援WNOHANG和WUNTRACED兩個選項,這是兩個常數,可以用"|"運算子把它們連線起來使用,比如:
ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);
|
ret=waitpid(-1,NULL,0);
|
而WUNTRACED引數,由於涉及到一些跟蹤除錯方面的知識,加之極少用到,這裡就不多費筆墨了,有興趣的讀者可以自行查閱相關材料。
看到這裡,聰明的讀者可能已經看出端倪了--wait不就是經過包裝的waitpid嗎?沒錯,察看<核心原始碼目錄>/include/unistd.h檔案349-352行就會發現以下程式段:
static inline pid_t wait(int * wait_stat)
|
waitpid的返回值比wait稍微複雜一些,一共有3種情況:
- 當正常返回的時候,waitpid返回收集到的子程式的程式ID;
- 如果設定了選項WNOHANG,而呼叫中waitpid發現沒有已退出的子程式可收集,則返回0;
- 如果呼叫中出錯,則返回-1,這時errno會被設定成相應的值以指示錯誤所在;
當pid所指示的子程式不存在,或此程式存在,但不是呼叫程式的子程式,waitpid就會出錯返回,這時errno被設定為ECHILD;
/* waitpid.c */
|
編譯並執行:
$ cc waitpid.c -o waitpid
|
父程式經過10次失敗的嘗試之後,終於收集到了退出的子程式。
因為這只是一個例子程式,不便寫得太複雜,所以我們就讓父程式和子程式分別睡眠了10秒鐘和1秒鐘,代表它們分別作了10秒鐘和1秒鐘的工作。父子程式都有工作要做,父程式利用工作的簡短間歇察看子程式的是否退出,如退出就收集它。
相關文章
- 【Linux】程式控制!!!Linux
- Linux 程式控制Linux
- Linux程式控制Linux
- Linux下程式相關:fork(),wait(),exec()LinuxAI
- Linux 等待程式結束 wait() 和 waitpid()LinuxAI
- Linux程式控制程式設計Linux程式設計
- LINUX程式如何管理控制(二)Linux
- LINUX(十一)Linux程式管理及作業控制Linux
- AIX的wait程式(即idle程式)AI
- Linux程式管理及作業控制(轉)Linux
- linux系統程式設計之程式(六):父程式查詢子程式的退出,wait,waitpidLinux程式設計AI
- 【WAIT】wait eventAI
- Lock wait timeout exceeded; try restarting transaction引數控制AIREST
- LINUX系統中程式如何管理控制(一)Linux
- Linux Shell程式設計(18)—— 迴圈控制Linux程式設計
- linux下如何釋放TIME_WAITLinuxAI
- Linux系統程式設計(8)—— 程式之程式控制函式forkLinux程式設計函式
- 修改linux最大檔案控制程式碼數Linux
- linux驅動程式:控制發光二極體Linux
- Linux中Sleep和Wait命令的使用方式LinuxAI
- Linux下開發-wait和waitpidLinuxAI
- 【go語言】wait,wait for meGoAI
- Linux系統程式設計(27)——執行緒控制Linux程式設計執行緒
- 【Mysql—Linux】系統調優,你所不知道的TIME_WAIT和CLOSE_WAITMySqlLinuxAI
- 阻塞程式函式 wait()和waitpid()函式AI
- 併發程式設計之Wait和Notify程式設計AI
- linux系統程式設計之程式(二):程式生命週期與PCB(程式控制塊)Linux程式設計
- Linux系統程式設計之程式控制(程式建立、終止、等待及替換)Linux程式設計
- Linux系統程式設計(9)—— 程式之程式控制函式exec系列函式Linux程式設計函式
- 控制程式碼表篇——程式控制程式碼表
- LINUX下解決TIME_WAIT過多問題LinuxAI
- 併發程式設計之 wait notify 方法剖析程式設計AI
- java併發程式設計系列:wait/notify機制Java程式設計AI
- [APUE] 程式控制
- fork waitAI
- oracle wait!OracleAI
- wait eventsAI
- wait() and notify()AI