日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux fork函数的精辟解说

發(fā)布時間:2023/12/15 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux fork函数的精辟解说 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

此文原文來源于一個blog,文章的名稱為:linux fork函數(shù)的精辟解說原文地址:http://blog.chinaunix.net/space.php?uid=12461657&do=blog&id=3062996感覺這篇文章不錯,在此分享下來,在原文的基礎(chǔ)上增加了自己的一些理解和說明。

  開始演示:[plain]view plaincopyprint?

  [root@test code]# cat fork.c #include <stdio.h> #include <unistd.h> #include <sys/types.h>

  main()

  { pid_t pid;pid=fork();if (pid < 0)

  printf("Error in fork!");else if (pid == 0)

  printf("I am the child process. The process id is %d\n",getpid());else printf("I am the parent process. The process id is %d\n",getpid());} [root@test code]# gcc fork.c -o fork [root@test code]# ./fork I am the child process. The process id is 6260 I am the parent process. The process id is 6259先說什么是進(jìn)程一個進(jìn)程,就是一個可執(zhí)行程序的一次執(zhí)行過程中的一個狀態(tài)。

  打個比方

  我們把一個大學(xué)數(shù)學(xué)老師比作一個可執(zhí)行程序,老師就是一個人,相當(dāng)于一份源碼,這個數(shù)學(xué)老師每個學(xué)期可能要教多個班,假設(shè)他教1班和2班,時間是一個學(xué)期,那么他從開學(xué)到期末教這兩個班這個過程就是兩個進(jìn)程,兩個進(jìn)程的周期都是一個學(xué)期。

  在稍微理解了進(jìn)程的概念之后,我們說在正在運行的計算機中,不管是Linux或者是Windows系統(tǒng)都運行有很多進(jìn)程,雖然我們的系統(tǒng)中進(jìn)程比較多,但是對于單核的CPU而言,每一時刻只能有一個進(jìn)程占用CPU,其他的進(jìn)程就可能處在等待執(zhí)行、就緒、結(jié)束等狀態(tài)(狀態(tài)名稱可能隨不同操作系統(tǒng)而相異)。

  那么要使我們的操作系統(tǒng)能夠正常執(zhí)行,操作系統(tǒng)對這些進(jìn)程的管理,典型的情況,是通過內(nèi)存中的進(jìn)程表完成的(這里的進(jìn)程表不是源碼的意思)。進(jìn)程表中的每一個表項,記錄的是當(dāng)前操作系統(tǒng)中一個進(jìn)程的情況,比如執(zhí)行到哪里,下一步要執(zhí)行什么命令等。

  一個稱為“程序計數(shù)器(program counter, pc)”的寄存器,指出當(dāng)前占用CPU的進(jìn)程要執(zhí)行的下一條指令的位置。當(dāng)分給某個進(jìn)程的CPU時間已經(jīng)用完,操作系統(tǒng)將該進(jìn)程相關(guān)的寄存器的值,保存到該進(jìn)程在進(jìn)程表中對應(yīng)的表項里面;然后把將要接替掉當(dāng)前進(jìn)程的那個進(jìn)程的上下文從內(nèi)存的進(jìn)程表中讀入,并更新相應(yīng)的寄存器。這個過程稱為“上下文交換(process context switch)”,實際的上下文交換需要涉及到更多的數(shù)據(jù),那和fork無關(guān),不再多說,主要要記住程序寄存器pc指出程序當(dāng)前已經(jīng)執(zhí)行到哪里,是進(jìn)程上下文的重要內(nèi)容,換出 CPU的進(jìn)程要保存這個寄存器的值,換入CPU的進(jìn)程,也要根據(jù)進(jìn)程表中保存的本進(jìn)程執(zhí)行上下文信息,更新這個寄存器)。

  好了,有這些概念打底,可以說fork了。當(dāng)你的程序執(zhí)行到下面的語句:pid=fork();操作系統(tǒng)會進(jìn)行如下的大概過程:創(chuàng)建一個新的子進(jìn)程,而這個子進(jìn)程是父進(jìn)程的副本,接下來這兩個進(jìn)行就由操作系統(tǒng)調(diào)度,直到程序執(zhí)行結(jié)束。

  那么這個過程,我們可以對其進(jìn)行更加詳細(xì)的分析。在執(zhí)行fork以后,操作系統(tǒng)復(fù)制一份當(dāng)前執(zhí)行的進(jìn)程的數(shù)據(jù),包括進(jìn)程的數(shù)據(jù)空間、堆和棧等,并且在進(jìn)程表中相應(yīng)為它建立一個新的表項。上下文也是原進(jìn)程(父進(jìn)程)的拷貝。但是父、子進(jìn)程共享正文段,也就是CPU執(zhí)行的機器指令部分,這個可共享的,在存儲器中只需要一個副本,而且這個副本通常是只讀的。

  那在什么時候父子進(jìn)程中就分道揚鑣呢?

  從上面的實驗結(jié)果我們看出那兩條打印出來的語句不是在同一個進(jìn)程里面的,因為在同一個進(jìn)程里面不可能存在,不通結(jié)果的getpid(),事實說明是兩個不同進(jìn)程返回的結(jié)果,那么在執(zhí)行pid=fork()以后,開始出現(xiàn)父、子進(jìn)程,既然是兩個進(jìn)程,那么接下來誰先被調(diào)度,也就是說執(zhí)行pid=fork()以后,在單核CPU下,只會有一個進(jìn)程被調(diào)度,假設(shè)是我們的父進(jìn)程占用CPU時間,父進(jìn)程繼續(xù)執(zhí)行,操作系統(tǒng)對fork的實現(xiàn),使這個調(diào)用在父進(jìn)程中返回剛剛創(chuàng)建的子進(jìn)程的pid(一個正整數(shù)),所以下面的if語句中pid<0, pid==0的兩個分支都不會執(zhí)行。所以輸出I am the parent process……。

  子進(jìn)程在之后的某個時候得到調(diào)度,它的上下文被換入。我們上面分析過,在子進(jìn)行創(chuàng)建的時候也會復(fù)制父進(jìn)程的上下文,所以子進(jìn)程不會從頭開始執(zhí)行,而是從pid=fork()開始執(zhí)行,基于操作系統(tǒng)對fork的實現(xiàn),使得子進(jìn)程中fork調(diào)用返回0.所以在這個進(jìn)程(中pid=0.這個進(jìn)程繼續(xù)執(zhí)行的過程中,if語句中 pid<0不滿足,但是pid==0是true.所以輸出I am the child process……。

  我們下面來看一個和我在上面分析的一個結(jié)論似乎存在矛盾的現(xiàn)象

  [plain]view plaincopyprint?

  [root@test code]# cat fork.c #include <stdio.h> #include <unistd.h> #include <sys/types.h>

  main()

  { pid_t pid;printf("fork!");pid=fork();if (pid < 0)

  printf("Error in fork!\n");else if (pid == 0)

  printf("I am the child process. The process id is %d\n",getpid());else printf("I am the parent process. The process id is %d\n",getpid());} [root@test code]# gcc fork.c -o fork [root@test code]# ./fork fork!I am the child process. The process id is 7378 fork!I am the parent process. The process id is 7377 [root@test code]#

  這里我添加了printf("fork!")這一行,執(zhí)行了以后我們發(fā)現(xiàn),“fork!”打印了兩次,我們上面不是說,fork以后的子進(jìn)程的上下文不是和父進(jìn)程一樣嗎,也就是說子進(jìn)程不會從頭開始執(zhí)行,應(yīng)該從fork執(zhí)行,那么fork!的出現(xiàn)不是有矛盾嗎?我們再來看看下面的現(xiàn)象

  [plain]view plaincopyprint?

  <span style="font-family:Courier New;">[root@test code]# cat fork.c #include <stdio.h> #include <unistd.h> #include <sys/types.h>

  main()

  { pid_t pid;printf("fork!\n");pid=fork();if (pid < 0)

  printf("Error in fork!\n");else if (pid == 0)

  printf("I am the child process. The process id is %d\n",getpid());else printf("I am the parent process. The process id is %d\n",getpid());} [root@test code]# gcc fork.c -o fork [root@test code]# ./fork fork!

  I am the child process. The process id is 7458 I am the parent process. The process id is 7457 [root@test code]#</span>

  這里我在printf("fork!")這一行的fork!后面添加了一個換行符,變成printf("fork!\n")執(zhí)行以后發(fā)現(xiàn)只打印一個fork!這個到底是什么原因呢?

  主要的區(qū)別是因為有了一個\n 回車符號,說起真正的原因,這和printf的緩沖機制有關(guān)了,printf某些內(nèi)容時,操作系統(tǒng)僅僅是把該內(nèi)容放到了stdout的緩沖隊列里了,并沒有實際的寫到屏幕上,但是只要看到有\(zhòng)n 則會立即刷新stdout,因此就馬上能夠打印了。

  還沒有執(zhí)行到fork()的時候,原進(jìn)程運行了printf("fork!") 后,fork!僅僅被放到了緩沖里,執(zhí)行了fork,這時候子進(jìn)程復(fù)制一份父進(jìn)程的數(shù)據(jù),包括這個stdout緩沖,在子進(jìn)程度stdout緩沖里面就也有了fork!。執(zhí)行到后面這兩個緩沖都打印到屏幕上,所以出現(xiàn)兩次,并不是printf執(zhí)行兩次。而運行 printf("fork!\n")后, fork!被立即打印到了屏幕上,之后fork到的子進(jìn)程里的stdout緩沖里不會有fork!內(nèi)容,因此你看到的結(jié)果會是fork!被printf了1次!!!

總結(jié)

以上是生活随笔為你收集整理的linux fork函数的精辟解说的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91色交| 国产在线观看一区 | 亚洲狠| 国产精品少妇 | 日韩不卡一区二区三区 | 一本一道波多野结衣av黑人 | 伊人网站在线观看 | 久久久久人妻一区二区三区 | 图片区小说区视频区 | 特黄1级潘金莲 | 91精品综合久久久久久五月天 | 国产一级爱c视频 | 2020自拍偷拍| 日韩少妇裸体做爰视频 | 欧美无吗 | 国产午夜无码精品免费看奶水 | 成人28深夜影院 | 亚洲4p| 男女av网站 | 中文字幕第315页 | 国产中文字幕在线视频 | 久久机热这里只有精品 | 色欲国产精品一区二区 | 91黑丝在线观看 | 欧美一级色图 | 午夜免费精品 | 99re6这里有精品热视频 | 午夜桃色| 国产在线一区视频 | 日皮毛片 | 毛片9| 日韩在线视频第一页 | 四虎在线影视 | 可以看av的网站 | 国产精品久久久久久亚洲毛片 | 91日本在线观看 | 狠狠躁18三区二区一区视频 | 欧美18av | 精彩视频一区二区三区 | 色射综合| 香蕉视频久久 | 海角社区id:1220.7126,10. | 欧美xxxx非洲 | 国产精品夜色一区二区三区 | 国产精品久久久久高潮 | 国产日产精品一区二区 | 丝袜美腿一区二区三区 | av中文字幕av | 色呦呦免费视频 | 9i免费看片黄 | 中文字幕久久精品 | 97爱视频| 日韩久久久久久久久 | 日韩精品一线二线三线 | 久久狠狠干 | 亚洲xx网| 福利视频91| 久久国产一区二区三区 | 亚洲国产一二三区 | 熟女性饥渴一区二区三区 | 亚洲综合区 | 91网站在线播放 | 国产chinese男男网站大全 | 天天拍天天操 | 香蕉视频三级 | 欧美在线a | 免费一区二区三区四区 | 一级片av| 色婷婷av在线| 日本伦理片在线播放 | 日韩精品一区二区三区在线 | 日本大奶少妇 | 久久大伊人 | 在线无码va中文字幕无码 | 在线中文视频 | 黄色片子一级 | 超碰自拍| 亚洲AV成人无码久久精品巨臀 | 日韩黄色录像 | 在线视频观看一区二区 | 成人中文字幕+乱码+中文字幕 | 亚洲精品国产一区二区 | 精品免费一区二区 | 黄色免费网站 | 婷婷午夜 | 久久一精品 | 影音先锋一区 | 国产精品高潮呻吟久久久久久 | 国产免费a级片 | 69xxx国产 | 欧美第一页 | 国产午夜精品久久久久久久久久 | 青青草在线免费观看 | 69av导航 | 黄色片在线免费观看视频 | 日韩一级视频在线观看 | 国产精品久久久久高潮 | 久久久精品人妻一区二区三区 | 青青草精品在线视频 |