Unix環境編程之 進程控制

進程終止:

vfork函數

vfork用於創建一個新進程,而新進程的目的是exec一個新程序,vfork與fork一樣都創建子進程,但是並不將父進程的地址空間完全複製到子進程中去,因爲子進程會立即調用exec,於是也就不會存訪該地址空間。
相反,它在調用exec之前,它在父進程空間運行。

另一個區別是:vfork保證子進程先運行,在它調用exec或exit之後,父進程纔可能被調度運行。

#include<stdio.h>
#include"apue.h"
#include<myerror.h>
int glob=6;
char buf[]="a write to stdout\n";
int main(void)
{
     int var;
      pid_t pid;

       var=88;

        if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1)
                 err_sys("write error");
         printf("before fork\n");
          if((pid=vfork())<0)
               {
                      err_sys("vfork error");

              }

           else if(pid==0)
                {
                       glob++;
                        var++;
                    _exit(0);
                 }

             printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);

             exit(0);

}




zsj@zsj-virtual-machine:~/ccode$ cc 8-2.c
zsj@zsj-virtual-machine:~/ccode$ ./a.out
a write to stdout
before fork
pid=15390,glob=7,var=89
zsj@zsj-virtual-machine:~/ccode$ 

子進程對變量golb,var做增1操作,結果改變了父進程中的變量值。因爲子進程在父進程的地址空間運行,所以這並不令人驚訝。作用的確與fork不同。

調用了_exit而不是exit。_exit並不執行標準I/O沖洗操作。如果調用的是exit,則該程序的輸出是不確定的。

exit函數

(1)在main函數內執行return語句。等效於使用exit
(2)在調用exit函數。此函數由ISO C定義,其操作包括調用各終止處理程序。然後關閉所有I/O流等。
(3)調用_exit 或_Exit函數。目的是爲進程提供一種無需運行終止處理程序或信號處理程序而終止的方法。
(4)進程的最後一個線程在其啓動例程中執行返回語句。
(5)進程中的最後一個線程調用pthread_exit函數。

對於以上的任何終止情形,我們都希望能夠通知其父進程它是如何終止的。對於三個終止函數,實現這一點的方法是,將其退出狀態作爲參數傳遞給函數。

在任何一種情況下,該終止進程的父進程都能用wait 或waitpid函數取得其終止狀態。

在說明fork函數時,顯而易見,子進程是調用fork後生成的。上面又說明了子進程將其終止狀態返回給父進程。但是如果父進程在子進程之前終止,那麼

對於父進程已經終止的所有進程,他們的父進程都改變爲init進程。我們稱這些進程由init進程領養。

如果子進程在父進程之前終止,那麼父進程又如何能在做相應檢查時得到子進程的終止狀態呢?

答案是內核爲每個終止子進程保存了一定量的信息,所以當父進程調用wait或waitpid時,可以得到這些信息。

這些信息至少包括進程ID,進程的終止狀態、以及該進程的CPU時間總量。內核可以釋放終止進程所有的存儲區、關閉所有其打開文件。
一個已經終止、但是其父進程尚未對其進行善後處理的進程稱爲僵死進程。

一個由init領養的進程終止時不會變成僵死進程。因爲只要進程終止,init就會調用一個wait函數取得其終止狀態。

wait 和waitpid函數

當一個進程正常或異常終止時,內核就向其父進程發送 SIGCHLD信號。因爲子進程終止是個異步事件,所以這種信號也是內核向父進程發的異步通知。

#include<sys/wait.h>
pid_wait(int *statloc);
pid_waitpid(pid_t pid,int *statloc,int options);

參數statloc是一個整型指針,如果staltloc不是一個空指針,則終止進程的終止狀態就放在它指向的單元裏。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章