新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > FORK()函數的理解

        FORK()函數的理解

        作者: 時間:2012-08-06 來源:網絡 收藏

        子進程和父進程都執行在fork調用之后的代碼,子進程是父進程的一個拷貝。例如,父進程的數據空間、堆棧空間都會給子進程一個拷貝,而不是共享這些內存。

        Current implementations don't perform. a complete copy of the parent's data, stack, and heap, since a fork is often followed by an exec. Instead, a technique called copy-on-write (COW) is used. These regions are shared by the parent and the child and have their protection changed by the kernel to read-only. If either process tries to modify these regions, the kernel then makes a copy of that piece of memory only, typically a page in a virtual memory system. Section 9.2 of Bach [1986] and Sections 5.6 and 5.7 of McKusick et al. [1996] provide more detail on this feature.

        我們來給出詳細的注釋

        #include

        #include

        int main(void)

        {

        pid_t pid;

        int count=0;

        /*此處,執行fork調用,創建了一個新的進程, 這個進程共享父進程的數據和堆棧空間等,這之后的代碼指令為子進程創建了一個拷貝。 fock 調用是一個復制進程,fock 不象線程需提供一個做為入口, fock調用后,新進程的入口就在 fock的下一條語句。*/

        pid = fork();

        /*此處的pid的值,可以說明fork調用后,目前執行的是父進程還是子進程*/

        printf( Now, the pid returned by calling fork() is %dn, pid );

        if ( pid>0 )

        {

        /*當fork在子進程中返回后,fork調用又向父進程中返回子進程的pid, 如是該段代碼被執行,但是注意的事,count仍然為0, 因為父進程中的count始終沒有被重新賦值, 這里就可以看出子進程的數據和堆棧空間和父進程是獨立的,而不是共享數據*/

        printf( This is the parent process,the child has the pid:%dn, pid );

        printf( In the parent process,count = %dn, count );

        }

        else if ( !pid )

        { /*在子進程中對count進行自加1的操作,但是并沒有影響到父進程中的count值,父進程中的count值仍然為0*/

        printf( This is the child process.n);

        printf( Do your own things here.n );

        count++;

        printf( In the child process, count = %dn, count );

        }

        else

        {

        printf( fork failed.n );

        }

        return 0;

        }

        也就是說,在Linux下一個進程在內存里有三部分的數據,就是代碼段、堆棧段和數據段。代碼段,顧名思義,就是存放了程序代碼的數據,假如機器中有數個進程運行相同的一個程序,那么它們就可以使用相同的代碼段。堆棧段存放的就是子程序的返回地址、子程序的參數以及程序的局部變量。而數據段則存放程序的全局變量,常數以及動態數據分配的數據空間(比如用malloc之類的取得的空間)。系統如果同時運行數個相同的程序,它們之間就不能使用同一個堆棧段和數據段。

        仔細分析后,我們就可以知道:

        一個程序一旦調用fork函數,系統就為一個新的進程準備了前述三個段,首先,系統讓新的進程與舊的進程使用同一個代碼段,因為它們的程序還是相同的,對于數據段和堆棧段,系統則復制一份給新的進程,這樣,父進程的所有數據都可以留給子進程,但是,子進程一旦開始運行,雖然它繼承了父進程的一切數據,但實際上數據卻已經分開,相互之間不再有影響了,也就是說,它們之間不再共享任何數據了。

        fork()不僅創建出與父進程代碼相同的子進程,而且父進程在fork執行點的所有上下文場景也被自動復制到子進程中,包括:

        ——全局和局部變量

        ——打開的文件句柄

        ——共享內存、消息等同步對象

        而如果兩個進程要共享什么數據的話,就要使用另一套函數(shmget,shmat,shmdt等)來操作。現在,已經是兩個進程了,對于父進程,fork函數返回了子程序的進程號,而對于子程序,fork函數則返回零,這樣,對于程序,只要判斷fork函數的返回值,就知道自己是處于父進程還是子進程中。

        pid控制相關文章:pid控制原理



        上一頁 1 2 下一頁

        關鍵詞: 理解 函數 FORK

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 平湖市| 万盛区| 曲麻莱县| 新晃| 张家界市| 台东市| 和顺县| 郯城县| 绵阳市| 邵阳市| 青川县| 金塔县| 易门县| 景洪市| 枝江市| 嘉禾县| 忻州市| 镇巴县| 辰溪县| 本溪| 禄丰县| 新昌县| 甘谷县| 监利县| 玉门市| 克什克腾旗| 龙泉市| 金阳县| 积石山| 奉化市| 玉门市| 阳春市| 丁青县| 神池县| 乌拉特后旗| 周宁县| 勐海县| 洞口县| 焦作市| 宜州市| 南乐县|