最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Linux--進(jìn)程(fork)

2023-03-17 22:32 作者:圣母和正負(fù)喜歡沒(méi)辦法  | 我要投稿

一、概述

1 fork():建立父進(jìn)程完整副本,作為子進(jìn)程的執(zhí)行。

子進(jìn)程獲得父進(jìn)程數(shù)據(jù) 空間、堆和棧的副本。注意,這是子進(jìn)程所擁有的副本。父進(jìn)程和子進(jìn)程并不共享這些存儲(chǔ)空間部分。父進(jìn)程和子進(jìn)程共享正文段。

內(nèi)存空間分布圖

exec():

裝載一個(gè)新的程序(可執(zhí)行映像)覆蓋當(dāng)前進(jìn)程內(nèi)存空間中的映像,從而執(zhí)行不同的任務(wù)。

exec系列函數(shù)在執(zhí)行時(shí)會(huì)直接替換掉當(dāng)前進(jìn)程的地址空間。

exec()執(zhí)行過(guò)程

子進(jìn)程調(diào)用exec()函數(shù)后,會(huì)替換掉原來(lái)的進(jìn)程程序,子進(jìn)程會(huì)進(jìn)行自己的進(jìn)程程序?qū)崿F(xiàn)。

CW技術(shù)(寫(xiě)時(shí)復(fù)制):

? ?

子進(jìn)程時(shí)復(fù)制過(guò)去的數(shù)據(jù)是沒(méi)用的(因?yàn)樽舆M(jìn)程執(zhí)行exec(),原有的數(shù)據(jù)會(huì)被清空)

既然很多時(shí)候復(fù)制給子進(jìn)程的數(shù)據(jù)是無(wú)效的,于是就有了Copy On Write這項(xiàng)技術(shù)。

原理:fork之后exec之前兩個(gè)進(jìn)程用的是相同的物理空間(內(nèi)存區(qū)),子進(jìn)程的代碼段、數(shù)據(jù)段、堆棧都是指向父進(jìn)程的物理空間,也就是說(shuō),兩者的虛擬空間不同,物理空間是同一個(gè)。當(dāng)父子進(jìn)程中有更改相應(yīng)段的行為發(fā)生時(shí),再為子進(jìn)程相應(yīng)的段分配物理空間

優(yōu)點(diǎn):減少延時(shí)、減少不必要的復(fù)制(fork()時(shí)父進(jìn)程數(shù)據(jù)段是只讀)、保證數(shù)據(jù)完整性。

缺點(diǎn):fork()之后,父子進(jìn)程還要繼續(xù)進(jìn)行寫(xiě)操作,那么會(huì)產(chǎn)生大量的分頁(yè)錯(cuò)誤(頁(yè)異常中斷page-fault)。

CW例子:

#include <stdio.h>??

#include <stdlib.h>??

#include <unistd.h>??

#include <sys/types.h>??

#include <sys/stat.h>??

#include <fcntl.h>??

#include <sys/wait.h>

#include <string.h>

??

int main(){??

? ? ? ? int fd;??

? ? ? ? char A[10];??

? ? ? ? char *child = "Child output\n";??

? ? ? ? fd = open("xxx.txt",O_RDWR|O_CREAT,0666);??

? ? ? ? printf("fd:%d\n",fd);?

? ? ? ? write(fd,"xxx.txt",7);??

? ? ? ? close(fd);

? ? ? ? fd = open("foobar.txt",O_RDONLY,0);

? ? ? ? printf("fd:%d\n",fd);

? ? ? ? if(fork()==0)

? ? ? ? {??

? ? ? ? ? ? ? ? fd = 1;

? ? ? ? ? ? ? ? write(fd,child,strlen(child)+1);

? ? ? ? ? ? ? ? exit(0);??

? ? ? ? }??

? ? ? ? printf("fd:%d\n",fd);

? ? ? ? read(fd,A,sizeof(A));

? ? ? ? close(fd);?

? ? ? ? A[10]='\0';??

? ? ? ? printf("A = %s\n",A);??

? ? ? ? exit(0);??

}??

#在使用的時(shí)候,就分配實(shí)際物理內(nèi)存給子進(jìn)程,沒(méi)使用就不分配,還是用父進(jìn)程資源。

調(diào)一次,返回兩次,fork()函數(shù)調(diào)用完成以后父進(jìn)程的虛擬存儲(chǔ)空間被拷貝給了子進(jìn)程的虛擬

存儲(chǔ)空間,因此也就實(shí)現(xiàn)了共享文件等操作。主要CW技術(shù)用于虛擬的存儲(chǔ)空間映射到物理存

儲(chǔ)空間的過(guò)程,就是有進(jìn)程寫(xiě)入時(shí),內(nèi)核就會(huì)在物理存儲(chǔ)器中開(kāi)辟一個(gè)新的物理頁(yè)面,將內(nèi)容

復(fù)制到新物理頁(yè)面,再寫(xiě)入。這種用時(shí)寫(xiě)入節(jié)省時(shí)間空間。

fork()例子:

1 int main(void)

{

int i;

for(i=0; i<2; i++){

fork();

printf("i");? ?

}

return 0;

}

1> 一次調(diào)用,兩次返回,如果返回是0,則是子進(jìn)程,如果返回值>0,則是父進(jìn)程(返回值是子進(jìn)程的pid)。

2> 在fork()的調(diào)用處,整個(gè)父進(jìn)程空間會(huì)原模原樣地復(fù)制到子進(jìn)程中,包括指令,變量值,程序調(diào)用棧,環(huán)境變量,緩沖區(qū),等等。

3> 塊設(shè)備一般都有緩存,而字符設(shè)備一般都沒(méi)有緩存,對(duì)于磁盤(pán)這個(gè)塊設(shè)備來(lái)說(shuō),“n”并不會(huì)引起緩沖區(qū)刷出的動(dòng)作,那是全緩沖,你可以使用setvbuf來(lái)設(shè)置緩沖區(qū)大小,或是用fflush刷緩存,建議用fflush(stdout)。

2?

int main(void)

{

int i;

for(i=0; i<2; i++){

fork();

printf("ppid=%d, pid=%d, i=%d n", getppid(), getpid(), i); // 有 n

}

sleep(10);

return 0;

}

1>??6次輸出

ppid=8858, pid=8518, i=0

ppid=8858, pid=8518, i=1

ppid=8518, pid=8519, i=0

ppid=8518, pid=8519, i=1

ppid=8518, pid=8520, i=1

ppid=8519, pid=8521, i=1

2> 查看進(jìn)程:pstree -p | grep fork

|-bash(8858)-+-fork(8518)-+-fork(8519)---fork(8521)

3 自己寫(xiě)個(gè)vim

#include <unistd.h>??

#include <stdio.h>??

?#include <stdlib.h>

int main ()? ?

{? ?

? ? pid_t fpid;?

? ? int count=0;

? ? fpid=fork();

? ? if (fpid < 0)? ?

? ? ? ? printf("failure!/n");? ?

? ? else if (fpid == 0) {??

? ? ? ? printf("child/n");? ?

? ? ? ? count++;??

? ? }??

? ? else {??

? ? ? ? printf("parent/n");? ?

? ? ? ? count++;??

? ? }??

? ? printf("%d/n",count);??

? ? return 0;??

}??

函數(shù)會(huì)有兩次返回,將子進(jìn)程的PID返回給父進(jìn)程,0返回給子進(jìn)程。


Linux--進(jìn)程(fork)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
民丰县| 都昌县| 慈溪市| 隆尧县| 南部县| 石渠县| 宁化县| 洛南县| 盘山县| 宜宾市| 中宁县| 西昌市| 雅江县| 黎城县| 河北区| 清苑县| 十堰市| 彭州市| 长沙市| 阳曲县| 沅陵县| 永兴县| 若尔盖县| 城口县| 铜梁县| 上栗县| 宝兴县| 汉阴县| 桐梓县| 绥阳县| 瑞昌市| 泸州市| 台北市| 高阳县| 石狮市| 台北县| 富平县| 澄城县| 女性| 阿拉尔市| 海盐县|