當多個程序都企圖對共享資料進行某種處理,而最後的結果又取決於程序執行的順序時,這種情況被稱之為競爭條件(race condition)。如果第乙個程序希望等待乙個子程序終止,則它必須呼叫wait
函式中的乙個。如果乙個程序要等待其父程序終止,則可以使用下列形式的迴圈:
while
(getppid()
!=1)sleep(1
);
這種形式的迴圈被稱之為輪詢(polling),它的問題是浪費了cpu時間,因為呼叫者每隔1s都被喚醒,然後進行條件測試。各種形式的程序間通訊(ipc)以及訊號機制都可以避免競爭條件和輪詢。
測試示例:
#include
"../../include/apue.h"
static
void
charatatime
(char*)
;int
main
(void
)else
if(pid ==0)
else
return0;
}static
void
charatatime
(char
*str)
結果如下:
由圖中可知,並未發生錯誤的輸出,但是這並不意味著競爭條件不存在,只是在這個測試系統上未能看到而已。
以下是對上面測試程式的修改版本,其中我們使用tell
和wait
函式。
#include
"../../include/apue.h"
static
volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
static
void
sig_usr
(int);
static
void
charatatime
(char*)
;void
tell_wait
(void);
void
wait_parent
(void);
void
tell_child
(pid_t)
;void
tell_parent
(pid_t)
;void
wait_child
(void);
intmain
(void
)else
if(pid ==0)
else
return0;
}static
void
charatatime
(char
*str)
static
void
sig_usr
(int signo)
/* one signal handler for sigusr1 and sigusr2 */
void
tell_wait
(void
)void
wait_parent
(void
)void
tell_child
(pid_t pid)
void
tell_parent
(pid_t pid)
void
wait_child
(void
)
結果如下:
有上圖可知,執行此程式後,輸出的結果不再會出現交叉混合的情形。
fork
函式建立新的子程序後,子程序往往要呼叫一種exec
函式以執行另乙個程式。當程序呼叫一種exec
函式時,該程序執行的程式完全替換為新程式,而新程式則從其main
函式開始執行。因為呼叫exec
並不建立新程序,所以前後的程序id並未改變。exec
只是用磁碟上的乙個新程式替換了當前程序的正文段、資料段、堆段和棧段。
以下有7種不同的exec
函式可供使用,它們被稱之為exec
函式。這些函式使得unix系統程序控制原語更加完善。用fork
可以建立新程序,用exec
函式可以初始執行新的程式。exit
和wait
函式可以處理終止和等待終止。這些函式就是我們需要的基本的程序控制原語。
#include
intexecl
(const
char
*pathname,
const
char
*arg0,..
./* (char *)0 */);
intexecv
(const
char
*pathname,
char
*const ar**)
;int
execle
(const
char
*pathname,
const
char
*arg0,..
./* (char *)0, char *const envp */);
intexecve
(const
char
*pathnamr,
char
*const ar**,
char
*const envp)
;int
execlp
(const
char
*filename,
const
char
*arg0,..
./* (char *)0 */);
intexecvp
(const
char
*filename,
char
*const ar**)
;int
fexecve
(int fd,
char
*const ar**,
char
*const envp)
;7個函式返回值:若出錯,返回-
1;若成功,不返回。
在很多unix實現中,這7個函式中只有execve
是核心函式,其他6個函式均是庫函式,它們最終都要呼叫該系統呼叫。這7個函式的關係如下:
測試示例:
#include
"/home/dunk/share/apue/include/apue.h"
#include
char
*env_init=
;int
main
(void
)else
if(pid ==0)
if(waitpid
(pid,
null,0
)<0)
err_sys
("wait error");
if((pid =
fork()
)<0)
else
if(pid ==0)
return0;
}
結果如下:
以下是echoall
執行程式的**:
#include
"/home/dunk/share/apue/include/apue.h"
intmain
(int argc,
char
*ar**)
程序控制之exec函式
1.exec函式 include int execl const char pathname,const char arg0,char 0 int execv const char pathname,const char argv int execle const char pathname,con...
8 9 程序控制 競爭條件
當多個程序都企圖對共享資料進行某種處理,而最後的結果又取決於程序執行的順序時,則我們認為發生了競爭條件 race condition 如果乙個程序要等待其父程序終止,則可以使用下列形式的迴圈 while getppid 1 sleep 1 這種形式的迴圈 稱為輪詢 polling 的問題是它浪費了c...
Linux程序控制 exec函式族
1 簡介 在linux中,並不存在exec 函式,exec指的是一組函式,一共有6個,分別是 include extern char environ int execl const char path,const char arg,int execlp const char file,const c...