目錄
進(jìn)程的概念及應(yīng)用
進(jìn)程的定義
進(jìn)程的ID
fork函數(shù)(進(jìn)程創(chuàng)建函數(shù))
????????多進(jìn)程(以及多線程)是現(xiàn)代計(jì)算機(jī)網(wǎng)絡(luò)的精髓。在之前,我們所做的諸如回聲服務(wù)器、回聲客戶端、文件收發(fā)等都是偏向基礎(chǔ)的單進(jìn)程應(yīng)用。而經(jīng)過前面的鋪墊,我們對(duì)Socket也有了一定了解。接下來(lái),讓我們一起正式開始探索真正的網(wǎng)絡(luò)編程吧!
進(jìn)程的概念及應(yīng)用
進(jìn)程的定義
????????進(jìn)程(Process)是計(jì)算機(jī)中程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。在早期面向進(jìn)程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中,進(jìn)程是程序的基本執(zhí)行實(shí)體;在當(dāng)代面向線程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中,進(jìn)程是線程的容器。程序是指令、數(shù)據(jù)及其組織形式的描述,進(jìn)程是程序的實(shí)體。
補(bǔ)充:
宏觀上,當(dāng)有多個(gè)進(jìn)程運(yùn)行在操作系統(tǒng)上時(shí),我們看到的效果是這些程序可以同時(shí)得到響應(yīng)。而從微觀上看,這些(程序的)進(jìn)程并非同時(shí)被執(zhí)行,而是通過在CPU分配的時(shí)間片中,借助CPU的高效計(jì)算能力,被反復(fù)快速地交替執(zhí)行,進(jìn)而讓我們視覺上看到的是“同時(shí)進(jìn)行”的效果。
進(jìn)程的ID
????????在操作系統(tǒng)中,所有進(jìn)程創(chuàng)建時(shí)都會(huì)被分配一個(gè)ID,我們將這個(gè)ID稱為“進(jìn)程ID”,其值為大于2的整數(shù)。值為1的進(jìn)程ID通常被分配給用于協(xié)助操作系統(tǒng)的系統(tǒng)應(yīng)用程序。
????????在Linux中,我們可以通過 ps 命令來(lái)查看當(dāng)前系統(tǒng)正在運(yùn)行的進(jìn)程,其用法如下:
????????????????????????ps [選項(xiàng),見下表]?
基本選項(xiàng) | 含義 |
?-A, -e | 所有進(jìn)程 |
?-a | 所有tty終端下的進(jìn)程,除了對(duì)話期首進(jìn)程 |
a | 所有tty終端下的進(jìn)程,包括其他用戶 |
-d | 全部進(jìn)程,除了會(huì)話期首進(jìn)程 |
-N, --deselect | 反選進(jìn)程(顯示進(jìn)程中未顯示的部分) |
r | 運(yùn)行中的進(jìn)程 |
T | 當(dāng)前終端下的所有進(jìn)程 |
x | 非tty終端控制下的進(jìn)程 |
????????如圖所示:
????????根據(jù)需要,還可進(jìn)一步顯示進(jìn)程細(xì)節(jié),具體用法可以通過?ps --help all 查閱,在這里不再贅述。
fork函數(shù)(進(jìn)程創(chuàng)建函數(shù))
????????在多進(jìn)程服務(wù)器端中,我們常用fork函數(shù)來(lái)創(chuàng)建進(jìn)程,具體用法如下:
#include <unistd.h>
pid_t fork(void);
//成功時(shí)返回進(jìn)程ID ,失敗時(shí)返回-1
????????fork函數(shù)會(huì)創(chuàng)建調(diào)用該函數(shù)的進(jìn)程的副本,即復(fù)制一份當(dāng)前調(diào)用了fork函數(shù)的進(jìn)程。副本進(jìn)程(子進(jìn)程)創(chuàng)建完成后,會(huì)同原進(jìn)程(父進(jìn)程)一起執(zhí)行fork函數(shù)調(diào)用完成后的語(yǔ)句。在判斷原進(jìn)程和副本進(jìn)程時(shí),需要通過fork函數(shù)的返回值來(lái)區(qū)分。
- 父進(jìn)程:fork函數(shù)返回子進(jìn)程ID
- 子進(jìn)程:fork函數(shù)返回0?
????????父進(jìn)程(Parent Process)指的是調(diào)用fork函數(shù)的主體,而子進(jìn)程(Child Process)是通過父進(jìn)程調(diào)用fork函數(shù)復(fù)制得來(lái)的進(jìn)程。?
????????調(diào)用fork函數(shù)后的程序運(yùn)行流程如下圖所示:
????????從圖中可以看出,父進(jìn)程調(diào)用fork函數(shù)時(shí)創(chuàng)建了一份子進(jìn)程,并由pid_t變量接收fork函數(shù)返回的進(jìn)程ID值。在這之前,子進(jìn)程繼承了父進(jìn)程之前的變量值(gval、lval)。不過在創(chuàng)建完成后,父進(jìn)程和子進(jìn)程的ID并不同,在父進(jìn)程中將執(zhí)行if條件滿足pid!=0的語(yǔ)句塊,即lval++;而子進(jìn)程將執(zhí)行pid==0的語(yǔ)句塊,即gval++。
????????讓我們來(lái)驗(yàn)證下思路:
????????fork.cpp
#include <stdio.h>
#include <unistd.h>
int gval = 10;
int main(int argc, char *argv[])
{
pid_t pid;
int lval = 20;
gval++; // gval -> 11
lval += 5; // lval -> 25
pid = fork();
if (pid == 0) // 子進(jìn)程
{
gval += 1; // gval -> 12
lval += 2; // lval -> 27
}
else // 父進(jìn)程
{
gval -= 1; // gval -> 10
lval -= 2; // lval -> 23
}
pid == 0 ? printf("Child Process: gval = %d, lval = %d \n", gval, lval)
: printf("Parent Process: gval = %d, lval = %d \n", gval, lval);
return 0;
}
????????輸出結(jié)果:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-487611.html
????????從運(yùn)行結(jié)果來(lái)看,驗(yàn)證了我們之前的想法的正確性。需要注意的是,調(diào)用fork函數(shù)后,父進(jìn)程之前的變量及其值在子進(jìn)程中是一致的(也拷貝了一份),但父、子進(jìn)程又有彼此完全獨(dú)立的內(nèi)存結(jié)構(gòu),因此在fork函數(shù)操作完成后執(zhí)行的下階段函數(shù)互不影響,結(jié)果彼此獨(dú)立。?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-487611.html
到了這里,關(guān)于【TCP/IP】多進(jìn)程服務(wù)器的實(shí)現(xiàn)(進(jìn)階) - 進(jìn)程的概念及fork函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!