- 論壇徽章:
- 0
|
在linux中,只有一個(gè)函數(shù)可以創(chuàng)建子進(jìn)程:fork。
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
由f o r k創(chuàng)建的新進(jìn)程被稱為子進(jìn)程( child process)。該函數(shù)被調(diào)用一次,但返回兩次。兩次返回的區(qū)別是子進(jìn)程的返回值是0,而父進(jìn)程的返回值則是新子進(jìn)程的進(jìn)程I D。將子進(jìn)程I D返回給父進(jìn)程的理由是:因?yàn)橐粋(gè)進(jìn)程的子進(jìn)程可以多于一個(gè),所以沒有一個(gè)函數(shù)使一個(gè)進(jìn)程可以獲得其所有子進(jìn)程的進(jìn)程I D。f o r k使子進(jìn)程得到返回值0的理由是:一個(gè)進(jìn)程只會有一個(gè)父進(jìn)程,所以子進(jìn)程總是可以調(diào)用g e t p p i d以獲得其父進(jìn)程的進(jìn)程I D (進(jìn)程ID 0總是由交換進(jìn)程使用,所以一個(gè)子進(jìn)程的進(jìn)程I D不可能為0 )。
子進(jìn)程和父進(jìn)程共享很多資源,除了打開文件之外,很多父進(jìn)程的其他性質(zhì)也由子進(jìn)程繼承:
• 實(shí)際用戶I D、實(shí)際組I D、有效用戶I D、有效組I D。
• 添加組I D。
• 進(jìn)程組I D。
• 對話期I D。
• 控制終端。
• 設(shè)置-用戶- I D標(biāo)志和設(shè)置-組- I D標(biāo)志。
• 當(dāng)前工作目錄。
• 根目錄。
• 文件方式創(chuàng)建屏蔽字。
• 信號屏蔽和排列。
• 對任一打開文件描述符的在執(zhí)行時(shí)關(guān)閉標(biāo)志。
• 環(huán)境。
• 連接的共享存儲段。
• 資源限制。
父、子進(jìn)程之間的區(qū)別是:
• fork的返回值。
• 進(jìn)程I D。
• 不同的父進(jìn)程I D。
• 子進(jìn)程的t m s _ u t i m e , t m s _ s t i m e , t m s _ c u t i m e以及t m s _ u s t i m e設(shè)置為0。
• 父進(jìn)程設(shè)置的鎖,子進(jìn)程不繼承。
• 子進(jìn)程的未決告警被清除。
• 子進(jìn)程的未決信號集設(shè)置為空集。
使f o r k失敗的兩個(gè)主要原因是:( a )系統(tǒng)中已經(jīng)有了太多的進(jìn)程(通常意味著某個(gè)方面出了問題),或者( b )該實(shí)際用戶I D的進(jìn)程總數(shù)超過了系統(tǒng)限制;貞洷2 - 7,其中C H I L D _ M A X規(guī)定了每個(gè)實(shí)際用戶I D在任一時(shí)刻可具有的最大進(jìn)程數(shù)。
f o r k有兩種用法:
(1) 一個(gè)父進(jìn)程希望復(fù)制自己,使父、子進(jìn)程同時(shí)執(zhí)行不同的代碼段。這在網(wǎng)絡(luò)服務(wù)進(jìn)程中是常見的——父進(jìn)程等待委托者的服務(wù)請求。當(dāng)這種請求到達(dá)時(shí),父進(jìn)程調(diào)用f o r k,使子進(jìn)程處理此請求。父進(jìn)程則繼續(xù)等待下一個(gè)服務(wù)請求。
(2) 一個(gè)進(jìn)程要執(zhí)行一個(gè)不同的程序。這對s h e l l是常見的情況。在這種情況下,子進(jìn)程在從f o r k返回后立即調(diào)用e x e c。
我們從一個(gè)例子程序中可以看到fork函數(shù)的作用,子進(jìn)程與父進(jìn)程之間的資源共享。
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int glob = 6;
char buf[] = "a write to stdout\n";
int main()
{
int var;
pid_t pid;
var = 88;
fprintf(stderr, "%s", buf);
printf("before fork\n");
if(( pid = fork() ) < 0 )
{
fprintf(stderr, "fork error\n");
}
else if(pid == 0)
{
glob++;
var++;
printf("child process\n");
printf("pid = %d, father pid = %d, glob = %d, var = %d\n", getpid(), getppid(), glob, var);
exit(0);
}
else
{
sleep(2);
printf("father process\n");
printf("pid = %d, father pid = %d, glob = %d, var = %d\n", getpid(), getppid(), glob, var);
}
return 0;
} |
|