亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

進程控制之fork函數

2024-06-28 13:28:36
字體:
來源:轉載
供稿:網友
進程控制之fork函數

一個現有進程可以調用fork函數創建一個新進程。

#include <unistd.h>pid_t fork( void );返回值:子進程中返回0,父進程中返回子進程ID,出錯返回-1

由fork創建的新進程被稱為子進程(child PRocess)。fork函數被調用一次,但返回兩次。兩次返回的唯一區別是子進程的返回值是0,而父進程的返回值則是新子進程的進程ID。將子進程ID返回給父進程的理由是:因為一個進程的子進程可以有多個,并且沒有一個函數使一個進程可以獲得其所有子進程的進程ID。fork使子進程得到返回值0的理由是:一個進程只會有一個父進程,所以子進程總是可以調用getppid以獲得其父進程的進程ID(進程ID 0總是由內核交換進程使用,所以一個子進程的進程ID不可能為0)。

子進程和父進程繼續執行fork調用之后的指令。子進程是父進程的副本。例如,子進程獲得父進程的數據空間、堆和棧的副本。注意,這是子進程所擁有的副本。父、子進程并不共享這些存儲空間部分。父、子進程共享正文段(text,代碼段)。

由于在fork之后經常跟隨著exec,所以現在的很多實現并不執行一個父進程數據段、棧和堆的完全復制。作為替代,使用了寫時復制(Copy-On-Write,COW)技術。這些區域由父、子進程共享,而且內核將它們的訪問權限改變為只讀的。如果父、子進程中的任一個試圖修改這些區域,則內核只為修改區域的那塊內存制作一個副本,通常是虛擬存儲器系統中的一“頁”。

linux 2.4.22提供了另一種新進程創建函數——clone(2)系統調用。這是一種fork的泛型,它允許調用者控制哪些部分由父、子進程共享。

程序清單8-1中的程序演示了fork函數,從中可以看到子進程對變量所作的改變并不影響父進程中該變量的值。

程序清單8-1 fork函數示例

[root@localhost apue]# cat prog8-1.c#include "apue.h"int     glob = 6;       /* external variable in initialized data */char    buf[] = "a write to stdout/n";intmain(void){        int     var;    /* automatic variable on the stack */        pid_t   pid;        var = 88;        if(write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) -1)                err_sys("write error");        printf("before fork/n");        /* we don't flush stdout */        if((pid = fork()) < 0)        {                err_sys("fork error");        }        else if(pid == 0)       /* child */        {                glob++;         /* modify variables */                var++;        }        else        {                sleep(2);       /* parent */        }        printf("pid = %d, glob = %d, var = %d/n", getpid(), glob, var);        exit(0);}

如果執行此程序則得到:

[root@localhost apue]# ./prog8-1a write to stdoutbefore forkpid = 13367, glob = 7, var = 89    子進程的變量值改變了pid = 13366, glob = 6, var = 88    父進程的變量值沒有改變[root@localhost apue]# ./prog8-1 > tmp.out[root@localhost apue]# cat tmp.outa write to stdoutbefore forkpid = 13369, glob = 7, var = 89before forkpid = 13368, glob = 6, var = 88

一般來說,在fork之后是父進程先執行還是子進程先執行是不確定的。這取決于內核所使用的調度算法。如果要求父、子進程之間相互同步,則要求某種形式的進程間通信。

當寫到標準輸出時,我們將buf長度減去1作為輸出字節數,這是為了避免將終止null字節寫出。strlen計算不包括終止null字節的字符串長度,而sizeof則計算包括終止null字節的緩沖區長度。兩者之間的另一個差別是,使用strlen需進行一次函數調用,而對于sizeof而言,因為緩沖區已用已知字符串進行了初始化,其長度是固定的,所以sizeof在編譯時計算緩沖區長度。

注意程序清單8-1中fork與I/O函數之間的交互關系。write函數是不帶緩沖的。因為在fork之前調用write,所以其數據寫到標準輸出一次。但是標準I/O庫是帶緩沖的(這里用到了標準I/O庫的printf函數)。如果標準輸出連到終端設備,則它是行緩沖的,否則它是全緩沖的。當以交互方式運行該程序時(此時是行緩沖的),只得到該printf輸出的行一次,其原因是標準輸出緩沖區在fork之前已由換行符沖洗。但是當將標準輸出重定向到一個文件時(此時是全緩沖的),卻得到printf輸出行兩次。其原因是,在fork之前調用了printf一次,但當調用fork時,該行數據仍在緩沖區中(我們沒有用fflush沖洗緩沖區),然后在將父進程數據空間復制到子進程中時,該緩沖區也被復制到子進程中于是那時父、子進程各自有了帶該行內容的標準I/O緩沖區。(子進程復制父進程緩沖區對程序的影響實例解析可參考:http://blog.csdn.net/lollipop_jin/article/details/8774057)在exit之前的第二個printf將其數據添加到現有的緩沖區中。當每個進程終止時,最終會沖洗其緩沖區中的副本。

文件共享

對程序清單8-1需注意的另一點是:在重定向父進程的標準輸出時,子進程的標準輸出也被重定向。實際上,fork的一個特性是父進程的所有打開文件描述符都被復制到子進程中。父、子進程的每個相同的打開描述符共享一個文件表項。

考慮下述情況,一個進程具有三個不同的打開文件,它們是標準輸入、標準輸出和標準出錯。在從fork返回時,我們有了如圖8-1所示的結構。

8-share-file

這種共享文件的方式使父、子進程對同一文件使用了一個文件偏移量。如果父、子進程寫到同一描述符文件,但又沒有任何形式的同步(例如使父進程等待子進程),那么它們的輸出就會相互混合(假定所有的描述符是在fork之前打開的)。

在fork之后處理文件描述符有兩種常見的情況

(1)父進程等待子進程完成。在這種情況下,父進程無需對其描述符做任何處理。當子進程終止后,它曾進行過讀、寫操作的任一共享描述符的文件偏移量已執行了相應的更新。

(2)父、子進程各自執行不同的程序段。在這種情況下,在fork之后,父、子進程各自關閉它們不需要使用的文件描述符,這樣就不會干擾對方使用的文件描述符。這種方法是網絡服務進程中經常使用的。

除了打開文件之外,父進程的很多其他屬性也由子進程繼承(可以理解為共享),包括:

  • 實際用戶ID、實際組ID、有效用戶ID、有效組ID。
  • 附加組ID。
  • 進程組ID。
  • 會話ID。
  • 控制終端。
  • 設置用戶ID標志和設置組ID標志。
  • 當前工作目錄。
  • 根目錄。
  • 文件模式創建屏蔽字。
  • 信號屏蔽和安排。
  • 針對任一打開文件描述符的在執行時關閉(close-on-exec)標志。
  • 環境。
  • 連接的共享存儲段。
  • 存儲映射。
  • 資源限制。

父、子進程之間的區別是:

  • fork的返回值。
  • 進程ID不同。
  • 兩個進程具有不同的父進程ID:子進程的父進程ID是創建它的進程的ID,而父進程的父進程ID則不變。
  • 子進程的tms_utime、tms_stime、tms_cutime已經tms_ustime均被設置為0.
  • 父進程設置的文件鎖不會被子進程繼承。
  • 子進程的未處理的鬧鐘(alarm)被清除。
  • 子進程的未處理信號集設置為空集。

使fork失敗的兩個主要原因是:系統中已經有了太多的進程(通常意味著某個方面出了問題),或者該實際用戶ID的進程總數超過了系統限制(CHILD_MAX)。

fork有下面兩種用法:

(1)一個父進程希望復制自己,使父、子進程同時執行不同的代碼段。這在網絡服務進程中是常見的——父進程等待客戶端的服務請求。當這種請求到達時,父進程調用fork,使子進程處理此請求。父進程則繼續等待下一個服務請求到達。

(2)一個進程要執行一個不同的程序。這對shell是常見的情況。在這種情況下,子進程從fork返回后立即調用exec。

某些操作系統將(2)中的兩個操作(fork之后執行exec)組合成一個,并稱其為spawn。UNIX將這兩個操作分開,因為在很多場合需要單獨使用fork,其后并不跟隨exec。另外,將這兩個操作分開,使得子進程在fork和exec之間可以更改自己的屬性。例如I/O重定向、用戶ID、信號安排等。

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品福利无圣光在线一区| 亚洲激情在线观看| 欧美精品video| 久久久伊人欧美| 亚洲毛片在线免费观看| 国产精品99久久久久久久久久久久| 午夜精品一区二区三区av| 欧美黑人巨大精品一区二区| 亚洲欧美制服综合另类| 奇米4444一区二区三区| www.日韩系列| 欧美激情综合亚洲一二区| 欧洲一区二区视频| 综合网日日天干夜夜久久| 欧美亚洲国产成人精品| 亚洲伊人成综合成人网| 日韩欧美亚洲综合| 亚洲欧美日本另类| 国产精品久久久久久五月尺| 亚洲欧洲成视频免费观看| 欧美亚洲一区在线| 中文字幕久热精品在线视频| 欧美激情高清视频| 欧美成人免费va影院高清| 精品久久久久久中文字幕| 欧洲亚洲免费在线| 亚洲最大福利视频网站| 欧美肥老太性生活视频| 国产精品无码专区在线观看| 国产成人精品优优av| 日韩av在线资源| 永久免费毛片在线播放不卡| 一本色道久久88综合日韩精品| 欧美黑人极品猛少妇色xxxxx| 国产精品久久网| 精品伊人久久97| 亚洲成**性毛茸茸| 亚洲精品在线91| 久久久久久国产三级电影| 91久久久久久久| 国产精品视频xxx| 亚洲最大成人网色| 68精品国产免费久久久久久婷婷| 粉嫩老牛aⅴ一区二区三区| 亚洲999一在线观看www| 欧美日韩亚洲网| 亚洲一区二区三区成人在线视频精品| 国产精品久久久久久久av电影| 久久久久亚洲精品| 精品久久久久久久久久久久久久| 少妇高潮久久久久久潘金莲| 欧美黄色性视频| 91人人爽人人爽人人精88v| 日韩精品视频在线播放| 欧美色道久久88综合亚洲精品| 日韩av在线导航| 欧美日韩国产精品一区二区不卡中文| 992tv成人免费影院| 国产亚洲视频在线| 欧美日韩一区二区精品| 国产精品18久久久久久麻辣| 亚洲人成毛片在线播放| 丁香五六月婷婷久久激情| 亚洲福利在线视频| 亚洲人成网站免费播放| 国产手机视频精品| 成人亲热视频网站| 久久视频在线免费观看| 97av在线播放| 欧美成年人在线观看| 欧美视频在线观看 亚洲欧| 亚洲国产私拍精品国模在线观看| 久久久久中文字幕2018| 国产精品成人品| 日韩中文字幕国产| 亚洲第一页自拍| 久久精品国产2020观看福利| 日韩中文字在线| 欧美黑人性猛交| 久久久亚洲成人| 国产精品无av码在线观看| 中文字幕日韩在线观看| 5278欧美一区二区三区| 国产成+人+综合+亚洲欧美丁香花| 欧美午夜片欧美片在线观看| 日韩欧亚中文在线| 精品久久久国产精品999| 精品久久久久久久久国产字幕| 国产亚洲欧洲高清一区| 久久久久久久国产精品视频| 91香蕉嫩草神马影院在线观看| 亚洲欧美精品伊人久久| 国产精品一区二区三| 国产精品私拍pans大尺度在线| 欧美性在线观看| 久久理论片午夜琪琪电影网| 综合激情国产一区| 91精品国产综合久久香蕉922| 欧美日韩第一页| 国产精品成人免费电影| 亚洲国产91精品在线观看| 91国产美女视频| 久久国产精品久久国产精品| 国产精品 欧美在线| 午夜精品久久17c| 羞羞色国产精品| 日韩高清人体午夜| 亚洲欧美制服综合另类| 欧美中文在线视频| 在线日韩精品视频| 欧美成人免费va影院高清| 伊人久久免费视频| 在线午夜精品自拍| 欧美性猛交xxxx偷拍洗澡| 久久久久女教师免费一区| 久久在线观看视频| 亚洲国产精品久久久久秋霞蜜臀| 亚洲精品999| 国产三级精品网站| 91香蕉国产在线观看| 国产精品福利小视频| 91欧美日韩一区| 久久伊人精品视频| 亚洲人成欧美中文字幕| 久久人人爽人人爽人人片av高清| 欧美一区二区三区艳史| 青青a在线精品免费观看| 欧美在线播放视频| 国产精品美乳在线观看| 亚洲欧美激情另类校园| 91tv亚洲精品香蕉国产一区7ujn| 国产成人avxxxxx在线看| 亚洲午夜精品久久久久久性色| 国产自摸综合网| 日韩在线不卡视频| 国产精品亚洲综合天堂夜夜| 日韩在线免费观看视频| 久久伊人精品视频| 久久99精品久久久久久噜噜| 成人精品久久久| 成人h片在线播放免费网站| 欧美成人精品不卡视频在线观看| 欧美有码在线视频| 国产欧美日韩免费| 成人免费观看49www在线观看| 精品中文字幕久久久久久| 亚洲欧美日韩久久久久久| 欧美精品一区二区三区国产精品| 国产精品一区久久| 亚洲欧美日韩第一区| 日韩国产欧美区| 欧美日韩视频在线| 久久人体大胆视频| 欧美裸体xxxx极品少妇| 91免费的视频在线播放| 操日韩av在线电影| 日韩国产高清视频在线| 隔壁老王国产在线精品| 在线观看中文字幕亚洲| 亚洲精品v欧美精品v日韩精品| 中文字幕av一区二区| 中文字幕一区二区三区电影| 国产日韩欧美影视| 日韩中文视频免费在线观看|