第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

1. 前言

之前的小節(jié)中介紹了操作系統(tǒng)的進程,操作系統(tǒng)中有個創(chuàng)建進程的重要方法就是 fork 函數(shù),當需要執(zhí)行和本進程相關(guān)的獨立任務(wù)時,一般需要創(chuàng)建一個有血緣關(guān)系的子進程。

2. fork 函數(shù)

面試官提問: Linux 系統(tǒng)中的 fork 函數(shù)是什么,有什么用途?

題目解析:

首先從定義上看,fork 函數(shù)的作用是在一個進程的基礎(chǔ)上創(chuàng)建新的進程,原有的進程被定義為父進程,新的進程被定義為子進程。

在 C 語言中調(diào)用 fork() 函數(shù)即實現(xiàn) fork 功能,示例:

#include<unistd.h>	//包含fork函數(shù)的頭文件
pid_t fork(void);	  //fork的返回類型為pid_t,我們可以看成int類型

認識一個函數(shù),需要從函數(shù)的定義入手,了解函數(shù)做了什么事情,入?yún)⑹鞘裁矗鰠⑹鞘裁?。我們?C 語言實現(xiàn)的一個典型的 fork 的程序入手,示例:

#include <unistd.h>
#include <stdio.h>
 
int main ()
{
    pid_t fpid; 
    int count = 0;
    fpid = fork();
    if (fpid == 0) { //返回值是0,說明是子進程
        printf("i am the child process, process id is %d\n", getpid());
        count++;
    } else if(fpid > 0) { //返回值>0,說明是父進程
        printf("i am the parent process, process id is %d\n", getpid());
        count++;
    } else { //返回值<0,說明fork發(fā)生異常
    	printf("fork encounter exception, process id is %d\n", getpid());
    }
    //打印計數(shù)器
    printf("after fork, counting result : %d\n", count);
    return 0;
}

在 MacOS 系統(tǒng)上編譯運行案例示例代碼,運行結(jié)果如下圖。

圖片描述

test.c 編譯執(zhí)行結(jié)果

如果是不了解函數(shù)原理的前提下,僅僅從代碼層面分析,在調(diào)用 fork() 函數(shù)之后,代碼會進入 if-else 判斷邏輯,在控制臺輸出一條語句,然后在控制臺打印計數(shù)器的數(shù)值。但是從真正執(zhí)行的結(jié)果來看,這兩個打印動作都分別執(zhí)行了兩次,并不符合我們的預(yù)期。fork 之后的代碼邏輯被執(zhí)行了兩次,而且兩次進入的不同的分支,所以重點在于 fork 函數(shù)到底有啥作用。

按照定義、入?yún)⒑统鰠⑷阶叩目蚣?,首先是分析函?shù)的定義,調(diào)用 fork 函數(shù)之后發(fā)生了什么事情:

(1)分配內(nèi)存:分配新的內(nèi)存空間給子進程;
(2)拷貝數(shù)據(jù):拷貝父進程的數(shù)據(jù)結(jié)構(gòu)給子進程;
(3)加入列表:將新生成的子進程添加到操作系統(tǒng)的進程列表;
(4)返回結(jié)果:fork 函數(shù)調(diào)度并且返回。

然后是分析 fork 函數(shù)的入?yún)ⅲ琭ork 函數(shù)入?yún)⑹?void,也就是自動同步進程的上下文,不需要手動聲明。

最后是分析 fork 函數(shù)的出參,fork 函數(shù)和程序員日常接觸的函數(shù)不同,我們在 C 或者 Java 中定義的函數(shù)只會有一個返回值,fork 函數(shù)則是調(diào)用一次,返回二次。調(diào)用方(例如上述案例的 main 函數(shù))根據(jù)返回值的不同判斷處于父進程還是子進程。

(1)返回值 < 0:調(diào)用失敗,一般是因為操作系統(tǒng)中的進程個數(shù)達到上限或者內(nèi)存不足以分配給新的進程;
(2)返回值 = 0:調(diào)用成功,并且處于子進程;
(3)返回值 > 0:調(diào)用成功,并且處于父進程。

現(xiàn)在就不難理解,從調(diào)用 fork() 函數(shù),代碼實際上是被父子進程分別執(zhí)行了一次,父進程的進程 id 是 52331,子進程的進程 id 是 52332。

在掌握原理之后,我們繼續(xù)探究 fork 函數(shù)的應(yīng)用場景。fork 函數(shù)的本質(zhì)在原有的進程基礎(chǔ)上創(chuàng)建一個新的進程,所以在網(wǎng)絡(luò)通信中使用較多,例如在客戶端發(fā)送一個 HTTP 請求打到服務(wù)器時,服務(wù)器進程 fork 出一個子進程用于處理單個請求,父進程則繼續(xù)等待其他的請求。

3. 小結(jié)

本章節(jié)介紹了 Linux 的 fork 函數(shù),fork 如同其英文名,就是進程的分叉。fork 函數(shù)簡化了操作系統(tǒng)的進程管理,又提供了一個簡單的多進程生成方案,在操作系統(tǒng)中的地位非常核心,候選人需要注意 fork 函數(shù)調(diào)用 1 次,返回 2 次的核心特性以及返回值。