APUE–fork()函數(shù)介紹
一、fork()系統(tǒng)調(diào)用介紹
1.fork()創(chuàng)建子進(jìn)程特點(diǎn)
fork()用于創(chuàng)建子進(jìn)程,一次調(diào)用會有兩個(gè)返回(return),一次返回給父進(jìn)程子進(jìn)程的PID(Process ID),一次返回給子進(jìn)程,其返回值為0.
- 返回值=0,子進(jìn)程在運(yùn)行
- 返回值>0,父進(jìn)程在運(yùn)行
- 返回值<0,fork()調(diào)用出錯(cuò)
進(jìn)程獲取自己的PID:getpid()
進(jìn)程獲取父進(jìn)程PID:getppid()
由于一個(gè)進(jìn)程可創(chuàng)建多個(gè)子進(jìn)程,沒有函數(shù)可以獲取其子進(jìn)程PID
2. 子進(jìn)程的特點(diǎn)
創(chuàng)建新的子進(jìn)程成功后,將父進(jìn)程的文本段、數(shù)據(jù)段、堆棧都復(fù)制一份給子進(jìn)程,但子進(jìn)程有自己獨(dú)立的空間,子進(jìn)程對這些內(nèi)存的修改并不會影響父進(jìn)程空間的相應(yīng)內(nèi)存。
父、子進(jìn)程執(zhí)行沒有固定的先后順序,哪個(gè)進(jìn)程先執(zhí)行要看系統(tǒng)的進(jìn)程調(diào)度策略。若要確保讓父進(jìn)程或子進(jìn)程先執(zhí)行,則需要程序員在代碼中通過進(jìn)程間通信的機(jī)制來實(shí)現(xiàn)
子進(jìn)程繼承的東西
- 進(jìn)程的資格、用戶號(UIDS)和組號(GIDS)
- 環(huán)境變量
- 內(nèi)存
- 打開的文件描述符
- 執(zhí)行時(shí)關(guān)閉標(biāo)志
- 信號控制設(shè)定
- nice值(由nice函數(shù)設(shè)定,進(jìn)程的優(yōu)先級,數(shù)值小的優(yōu)先級高)
- 進(jìn)程調(diào)度類別
- 進(jìn)程組號
- 對話期ID
- 當(dāng)前工作目錄
- 根目錄
- 文件方式創(chuàng)建屏蔽字
- 資源控制
- 控制終端
子進(jìn)程獨(dú)有
- 進(jìn)程號
- 不同的父進(jìn)程號
- 自己的文件描述符、目錄流的拷貝
- 資源使用設(shè)定為0
- 不繼承父進(jìn)程的進(jìn)程、正文、數(shù)據(jù)和其他鎖定內(nèi)存
- tms結(jié)構(gòu)中的系統(tǒng)時(shí)間
- 阻塞信號集初始化為空集
- time_create函數(shù)創(chuàng)建的計(jì)時(shí)器
- 異步輸入和輸出
- 父進(jìn)程設(shè)置的鎖
二、代碼示例
1.fork()創(chuàng)建子線程
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
int main(int argc, char **argv)
{
pid_t pid;
printf("Parent process PID[%d] start running...\n",getpid() );
pid = fork(); //創(chuàng)建子進(jìn)程
if( pid < 0 ) //fork()錯(cuò)誤
{
printf("fock() create child process failure:%s\n",strerror(errno));
return -1;
}
else if( 0 == pid ) //子進(jìn)程正在運(yùn)行
{
printf("Child process PID[%d] start running,my parent PID is [%d]\n", getpid(),getppid());
return 0;
}
else if( pid >0 ) //父進(jìn)程正在運(yùn)行
{
printf("Parent process PID[%d] continue running,and child process PID is [%d]\n",getpid(),pid);
return 0;
}
}
2.子進(jìn)程對內(nèi)存修改
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
int g_var = 7;
char g_buf[]="A string write to stdout.\n";
int main(int argc, char ** argv)
{
int var = 85;
pid_t pid;
if( write(STDOUT_FILENO,g_buf,sizeof(g_buf)-1) < 0 ) //將g_buf[]中的內(nèi)容輸出到屏幕上,除\n(換行)外,
{
printf("write string to stdout error:%s\n",strerror(errno));
return -1;
}
printf("Before fork\n");
if( (pid=fork()) < 0 ) //fork出錯(cuò)
{
printf("fork() error:%s\n",strerror(errno));
return -2;
}
else if( 0 == pid ) //子進(jìn)程正在運(yùn)行
{
printf("Child process PID[%d] running...\n",getpid());
g_var ++;
var ++;
}
else //父進(jìn)程正在運(yùn)行
{
printf("Parent process PID[%d] waiting...\n",getpid());
sleep(1); //讓子進(jìn)程先運(yùn)行
}
printf("PID=%ld,g_var=%d,var=%d\n",(long)getpid(),g_var,var);
return 0;
}
程序執(zhí)行結(jié)果如下:文章來源:http://www.zghlxwxcb.cn/news/detail-402656.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-402656.html
到了這里,關(guān)于fork()函數(shù)創(chuàng)建子進(jìn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!