系統(tǒng)之家 - 系統(tǒng)光盤(pán)下載網(wǎng)站!

當(dāng)前位置:系統(tǒng)之家 > 系統(tǒng)教程 > Linux系統(tǒng)調(diào)用fork()函數(shù)

Linux系統(tǒng)調(diào)用fork()函數(shù)的方法

時(shí)間:2015-04-13 16:53:28 作者:qipeng 來(lái)源:系統(tǒng)之家 1. 掃描二維碼隨時(shí)看資訊 2. 請(qǐng)使用手機(jī)瀏覽器訪問(wèn): https://m.xitongzhijia.net/xtjc/20150413/45052.html 手機(jī)查看 評(píng)論

  fork()函數(shù)是分叉函數(shù),現(xiàn)有的進(jìn)程可以調(diào)用fork()函數(shù)來(lái)新建一個(gè)新進(jìn)程,那么在Linux下要如何調(diào)用fork()函數(shù)呢?又或者fork()函數(shù)要如何在Linux下實(shí)現(xiàn)呢?隨小編一起來(lái)瞧瞧吧。

 Linux系統(tǒng)調(diào)用fork()函數(shù)的方法

  1.傳統(tǒng)的fork()系統(tǒng)調(diào)用直接把所有的資源復(fù)制給新創(chuàng)建的進(jìn)程.Linux的fork()使用寫(xiě)時(shí)拷貝(copy-on-write)頁(yè)實(shí)現(xiàn)。寫(xiě)時(shí)拷貝是一種可以推遲甚至免除拷貝數(shù)據(jù)的技術(shù),內(nèi)核此時(shí)并不復(fù)制整個(gè)進(jìn)程地址空間,而是讓父進(jìn)程和子進(jìn)程共享同一個(gè)拷貝。

  只有在需要寫(xiě)入的時(shí)候,數(shù)據(jù)才會(huì)被復(fù)制,從而使各個(gè)進(jìn)程擁有各自的拷貝,也就是說(shuō),資源的復(fù)制只有在需要寫(xiě)入的時(shí)候才進(jìn)行,在此之前,只是以只讀的方式共享。這種技術(shù)使地址空間上的頁(yè)的拷貝被推遲到實(shí)際發(fā)生寫(xiě)入的時(shí)候才進(jìn)行。在頁(yè)跟本不會(huì)被寫(xiě)入的情況下(比如:fork()后立即調(diào)用exec())它們就無(wú)需復(fù)制了。

  2.linux通過(guò)系統(tǒng)調(diào)用clone()來(lái)實(shí)現(xiàn)fork()。然后由clone()來(lái)調(diào)用do_fork()。

  linux下fork()函數(shù)的實(shí)現(xiàn):

  Linux通過(guò)clone()系統(tǒng)調(diào)用實(shí)現(xiàn)fork()。這個(gè)調(diào)用通過(guò)一系列的參數(shù)標(biāo)志來(lái)指明父,子進(jìn)程需要共享的資源。fork(),vfork()和__clone()庫(kù)函數(shù)都根據(jù)各自需要的參數(shù)標(biāo)志去調(diào)用clone()。然后由clone()去調(diào)用do_fork()。

  do_frok完成了創(chuàng)建中的大部分工作,它的定義在ker/frok.c文件中。該函數(shù)調(diào)用copy_process()的函數(shù),然后讓進(jìn)程開(kāi)始運(yùn)行。copy_process()函數(shù)完成的工作很有意思:

  1.調(diào)用dup_task_struct()為新進(jìn)程創(chuàng)建一個(gè)內(nèi)核棧,thread_info結(jié)構(gòu)和task_struct,這些值與當(dāng)前進(jìn)程的值相同。此時(shí),子進(jìn)程和父進(jìn)程的描述符是完全相同的。

  2.檢查新創(chuàng)建的這個(gè)子進(jìn)程后,當(dāng)前用戶所擁有的進(jìn)程數(shù)目沒(méi)有超出給它分配的資源的限制。

  3.現(xiàn)在,子進(jìn)程著手使自己與父進(jìn)程區(qū)別開(kāi)來(lái)。進(jìn)程描述符內(nèi)的許多成員都要被清0或者設(shè)為初始值。進(jìn)程描述符的成員值并不是繼承而來(lái)的,而主要是統(tǒng)計(jì)信息。進(jìn)程描述符中的大多數(shù)數(shù)據(jù)都是共享的。

  4.接下來(lái),子進(jìn)程的狀態(tài)被設(shè)置為T(mén)ASK_UNINTERRUPTIBLE以保證它不會(huì)投入運(yùn)行。

  5.copy_process()調(diào)用copy_flags()以更新task_struct的flags成員。表明進(jìn)程是否擁有超級(jí)用戶權(quán)限的PF_SUPERPRIV的標(biāo)志被清0.表明進(jìn)程還沒(méi)有調(diào)用exec()函數(shù)的PF_FORKNOEXEC標(biāo)志被設(shè)置。

  6.調(diào)用get_pid()為新進(jìn)程獲取一個(gè)有效的PID。

  7.根據(jù)傳遞給clone()的參數(shù)標(biāo)志,copy_process()拷貝或共享打開(kāi)的文件,文件系統(tǒng)信息,信號(hào)處理函數(shù),進(jìn)程地址空間和命名空間等。再一半情況下,這些資源會(huì)被給定進(jìn)程的所有線程共享;否則,這些資源對(duì)每個(gè)進(jìn)程是不同的,因此被拷貝到了這里。

  8.讓父進(jìn)程和子進(jìn)程平分剩余的時(shí)間片。

  9.最后,copy_process()做掃尾工作并返回一個(gè)指向子進(jìn)程的指針。

  再回到do_fork()函數(shù),如果copy_process()函數(shù)返回成功,新創(chuàng)建的子進(jìn)程被喚醒并讓其投入運(yùn)行。內(nèi)核有意選擇子進(jìn)程首先執(zhí)行。因?yàn)橐话胱舆M(jìn)程都會(huì)馬上調(diào)用exec()函數(shù),這樣可以避免寫(xiě)時(shí)拷貝的額外開(kāi)銷,如果父進(jìn)程首先執(zhí)行的話,有可能會(huì)開(kāi)始向地址空間寫(xiě)入。

  上面就是Linux調(diào)用fork()函數(shù)的方法介紹了,本文除了介紹了Linux下調(diào)用fork()函數(shù)的方法,還對(duì)fork()函數(shù)的實(shí)現(xiàn)做了詳細(xì)介紹,希望對(duì)你有所幫助。

標(biāo)簽 函數(shù)

發(fā)表評(píng)論

0

沒(méi)有更多評(píng)論了

評(píng)論就這些咯,讓大家也知道你的獨(dú)特見(jiàn)解

立即評(píng)論

以上留言僅代表用戶個(gè)人觀點(diǎn),不代表系統(tǒng)之家立場(chǎng)

其他版本軟件

熱門(mén)教程

人氣教程排行

Linux系統(tǒng)推薦

官方交流群 軟件收錄