【Linux教程】Linux系統(tǒng)零基礎(chǔ)編程入門(mén)慕趴,想當(dāng)大神?這些你都要學(xué)~

??文件和文件系統(tǒng)

? ? ? ?文件是Linux系統(tǒng)中最重要的抽象鄙陡,大多數(shù)情況下你可以把linux系統(tǒng)中的任何東西都理解為文件冕房,很多的交互操作其實(shí)都是通過(guò)文件的讀寫(xiě)來(lái)實(shí)現(xiàn)的。

? 文件描述符

? ? ? ?在Linux內(nèi)核中趁矾,文件是用一個(gè)整數(shù)來(lái)表示的耙册,稱(chēng)為?文件描述符,通俗的來(lái)說(shuō)毫捣,你可以理解它是文件的id(唯一標(biāo)識(shí)符)

??普通文件

??????普通文件就是字節(jié)流組織的數(shù)據(jù)详拙。

??????文件并不是通過(guò)和文件名關(guān)聯(lián)來(lái)實(shí)現(xiàn)的帝际,而是通過(guò)關(guān)聯(lián)索引節(jié)點(diǎn)來(lái)實(shí)現(xiàn)的,文件節(jié)點(diǎn)擁有文件系統(tǒng)為普通文件分配的唯一整數(shù)值(ino)饶辙,并且存放著一些文件的相關(guān)元數(shù)據(jù)蹲诀。

??目錄與鏈接

????? 正常情況下文件是通過(guò)文件名來(lái)打開(kāi)的。

? ????目錄是可讀名稱(chēng)到索引編號(hào)之間的映射弃揽,名稱(chēng)和索引節(jié)點(diǎn)之間的配對(duì)稱(chēng)為鏈接脯爪。

??????可以把目錄看做普通文件,只是它包含著文件名稱(chēng)到索引節(jié)點(diǎn)的映射(鏈接)


??進(jìn)程

? ? ? ?進(jìn)程是僅次于文件的抽象概念蹋宦,簡(jiǎn)單的理解披粟,進(jìn)程就是正在執(zhí)行的目標(biāo)代碼,活動(dòng)的冷冗,正在運(yùn)行的程序守屉。不過(guò)在復(fù)雜情況下,進(jìn)程還會(huì)包含著各種各樣的數(shù)據(jù)蒿辙,資源拇泛,狀態(tài)甚至虛擬計(jì)算機(jī)。

你可以這么理解進(jìn)程:它是競(jìng)爭(zhēng)計(jì)算機(jī)資源的基本單位思灌。

??進(jìn)程俺叭、程序與線(xiàn)程

? ????程序

? ? ? ?程序,簡(jiǎn)單的來(lái)說(shuō)就是存在磁盤(pán)上的二進(jìn)制文件泰偿,是可以?xún)?nèi)核所執(zhí)行的代碼

? ????進(jìn)程

? ? ? ?當(dāng)一個(gè)用戶(hù)啟動(dòng)一個(gè)程序熄守,將會(huì)在內(nèi)存中開(kāi)啟一塊空間,這就創(chuàng)造了一個(gè)進(jìn)程耗跛,一個(gè)進(jìn)程包含一個(gè)獨(dú)一無(wú)二的PID裕照,和執(zhí)行者的權(quán)限屬性參數(shù),以及程序所需代碼與相關(guān)的資料调塌。

? ? ? ?進(jìn)程是系統(tǒng)分配資源的基本單位晋南。

? ? ? ?一個(gè)進(jìn)程可以衍生出其他的子進(jìn)程,子進(jìn)程的相關(guān)權(quán)限將會(huì)沿用父進(jìn)程的相關(guān)權(quán)限羔砾。

? ????線(xiàn)程

? ? ? ?每個(gè)進(jìn)程包含一個(gè)或多個(gè)線(xiàn)程负间,線(xiàn)程是進(jìn)程內(nèi)的活動(dòng)單元,是負(fù)責(zé)執(zhí)行代碼和管理進(jìn)程運(yùn)行狀態(tài)的抽象姜凄。

? ? ? ?線(xiàn)程是獨(dú)立運(yùn)行和調(diào)度的基本單位政溃。


??進(jìn)程的層次結(jié)構(gòu)(父進(jìn)程與子進(jìn)程)

? ? ? ?在進(jìn)程執(zhí)行的過(guò)程中可能會(huì)衍生出其他的進(jìn)程,稱(chēng)之為子進(jìn)程檀葛,子進(jìn)程擁有一個(gè)指明其父進(jìn)程PID的PPID玩祟。子進(jìn)程可以繼承父進(jìn)程的環(huán)境變量和權(quán)限參數(shù)。

? ? ? ?于是屿聋,linux系統(tǒng)中就誕生了進(jìn)程的層次結(jié)構(gòu)——進(jìn)程樹(shù)空扎。

? ? ? ?進(jìn)程樹(shù)的根是第一個(gè)進(jìn)程(init進(jìn)程)藏鹊。

??????過(guò)程調(diào)用的流程: fork & exec

? ? ? ?一個(gè)進(jìn)程生成子進(jìn)程的過(guò)程是,系統(tǒng)首先復(fù)制(fork)一份父進(jìn)程转锈,生成一個(gè)暫存進(jìn)程盘寡,這個(gè)暫存進(jìn)程和父進(jìn)程的區(qū)別是pid不一樣夷磕,而且擁有一個(gè)ppid扼脐,這時(shí)候系統(tǒng)再去執(zhí)行(exec)這個(gè)暫存進(jìn)程,讓他加載實(shí)際要運(yùn)行的程序软棺,最終成為一個(gè)子進(jìn)程的存在砌溺。

??????進(jìn)程的結(jié)束

? ? ? ?當(dāng)一個(gè)進(jìn)程終止時(shí)影涉,并不會(huì)立即從系統(tǒng)中刪除,內(nèi)核將在內(nèi)存中保存該進(jìn)程的部分內(nèi)容规伐,允許父進(jìn)程查詢(xún)其狀態(tài)(這個(gè)被稱(chēng)為等待終止進(jìn)程)蟹倾。

? ? ? ?當(dāng)父進(jìn)程確定子進(jìn)程已經(jīng)終止,該子進(jìn)程將會(huì)被徹底刪除猖闪。

? ? ? ?但是如果一個(gè)子進(jìn)程已經(jīng)終止鲜棠,但父進(jìn)程卻不知道它的狀態(tài),這個(gè)進(jìn)程將會(huì)成為?僵尸進(jìn)程

??服務(wù)與進(jìn)程

簡(jiǎn)單的說(shuō)服務(wù)(daemon)就是常駐內(nèi)存的進(jìn)程培慌,通常服務(wù)會(huì)在開(kāi)機(jī)時(shí)通過(guò)init.d中的一段腳本被啟動(dòng)豁陆。


??進(jìn)程通信

? ? ? ?進(jìn)程通信的幾種基本方式:管道,信號(hào)量吵护,消息隊(duì)列盒音,共享內(nèi)存,快速用戶(hù)控件互斥馅而。


??程序里逆,進(jìn)程和線(xiàn)程

? ? ? ?現(xiàn)在我們?cè)俅卧敿?xì)的討論這三個(gè)概念

??????程序(program)

? ? ? ?程序是指編譯過(guò)的、可執(zhí)行的二進(jìn)制代碼用爪,保存在儲(chǔ)存介質(zhì)上,不運(yùn)行胁镐。

??????進(jìn)程(process)

? ? ? ?進(jìn)程是指正在運(yùn)行的程序偎血。

? ? ? ?進(jìn)程包括了很多資源,擁有自己獨(dú)立的內(nèi)存空間盯漂。

??????線(xiàn)程

? ? ? ?線(xiàn)程是進(jìn)程內(nèi)的活動(dòng)單元颇玷。

? ? ? ?包括自己的虛擬儲(chǔ)存器,如棧就缆、進(jìn)程狀態(tài)如寄存器帖渠,以及指令指針。

在單線(xiàn)程的進(jìn)程中竭宰,線(xiàn)程即進(jìn)程空郊。而在多線(xiàn)程的進(jìn)程中份招,多個(gè)線(xiàn)程將會(huì)共享同一個(gè)內(nèi)存地址空間


? 運(yùn)行一個(gè)進(jìn)程

? ? ? ?創(chuàng)建一個(gè)進(jìn)程,在unix系統(tǒng)中被分為了兩個(gè)流程狞甚。

????????● 把程序載入內(nèi)存并執(zhí)行程序映像的操作:exec

????????● 創(chuàng)建一個(gè)新進(jìn)程:fork

??exec

? ??? 最簡(jiǎn)單的exec系統(tǒng)調(diào)用函數(shù):execl()

????????● 函數(shù)原型:

int execl(const char * path,const chr * arg,...)

execl()調(diào)用將會(huì)把path所指的路徑的映像載入內(nèi)存锁摔,替換當(dāng)前進(jìn)程的映像。

參數(shù)arg是以第一個(gè)參數(shù)哼审,參數(shù)內(nèi)容是可變的谐腰,但最后必須以NULL結(jié)尾。

? ??????●?舉例:

int ret;

ret = execl("/bin/vi","vi",NULL);

if (ret == -1) {

? ? perror("execl");

}

? ? ? ?上面的代碼將會(huì)通過(guò)/bin/vi替換當(dāng)前運(yùn)行的程序

? ? ? ?注意這里的第一個(gè)參數(shù)vi涩盾,是unix系統(tǒng)的默認(rèn)慣例十气,當(dāng)創(chuàng)建、執(zhí)行進(jìn)程時(shí)春霍,shell會(huì)把路徑中的最后部分放入新進(jìn)程的第一個(gè)參數(shù)砸西,這樣可以使得進(jìn)程解析出二進(jìn)制映像文件的名字。

int ret;

ret = execl("/bin/vi","vi","/home/mark/a.txt",NULL);

if (ret == -1) {

? ? perror("execl");

}

? ? ? ?上面的代碼是一個(gè)非常有代表性的操作终畅,這相當(dāng)于你在終端執(zhí)行以下命令:

vi /home/mark/a.txt

? ??????●?返回值:

? ? ? ?正常情況下其實(shí)execl()不會(huì)返回籍胯,調(diào)用成功后會(huì)跳轉(zhuǎn)到新的程序入口點(diǎn)。

? ? ? ?成功的execl()調(diào)用离福,將改變地址空間和進(jìn)程映像杖狼,還改變了很多進(jìn)程的其他屬性。

? ? ? ?不過(guò)進(jìn)程的PID,PPID,優(yōu)先級(jí)等參數(shù)將會(huì)被保留下來(lái)妖爷,甚至?xí)A粝滤蜷_(kāi)的文件描述符(這就意味著它可以訪(fǎng)問(wèn)所有這些原本進(jìn)程打開(kāi)的文件)蝶涩。

? ? ? ?失敗后將會(huì)返回-1,并更新errno絮识。

????????●?其他exec系函數(shù)

? ? ? ?略绿聘,使用時(shí)查找


??fork

通過(guò)fork()系統(tǒng)調(diào)用,可以創(chuàng)建一個(gè)和當(dāng)前進(jìn)程映像一模一樣的子進(jìn)程次舌。

????●?函數(shù)原型

pid_t fork(void)

調(diào)用成功后熄攘,會(huì)創(chuàng)建一個(gè)新的進(jìn)程(子進(jìn)程),這兩個(gè)進(jìn)程都會(huì)繼續(xù)運(yùn)行彼念。

????●?返回值

如果調(diào)用成功挪圾,

父進(jìn)程中,fork()會(huì)返回子進(jìn)程的pid逐沙,在子進(jìn)程中返回0哲思;

如果失敗,返回-1吩案,并更新errno棚赔,不會(huì)創(chuàng)建子進(jìn)程。

? ??●?舉例

我們看下面這段代碼

#include <unistd.h>

#include <stdio.h>

int main ()

{

? ? pid_t fpid; //fpid表示fork函數(shù)返回的值

? ? int count=0;

? ? printf("this is a process\n");

? ? fpid=fork();

? ? if (fpid < 0)

? ? ? ? printf("error in fork!");

? ? else if (fpid == 0) {

? ? ? ? printf("i am the child process, my process id is %d\n",getpid());

? ? ? ? printf("我是爹的兒子\n");

? ? ? ? count++;

? ? }

? ? else {

? ? ? ? printf("i am the parent process, my process id is %d\n",getpid());

? ? ? ? printf("我是孩子他爹\n");

? ? ? ? count++;

? ? }

? ? printf("統(tǒng)計(jì)結(jié)果是: %d\n",count);

? ? return 0;

}

這段代碼的運(yùn)行結(jié)果比較神奇,是這樣的:


this is a process

i am the parent process, my process id is 21448

我是孩子他爹

統(tǒng)計(jì)結(jié)果是: 1

i am the child process, my process id is 21449

我是爹的兒子

統(tǒng)計(jì)結(jié)果是: 1


? ? ? ?在執(zhí)行了fork()之后靠益,這個(gè)程序就擁有了兩個(gè)進(jìn)程丧肴,父進(jìn)程和子進(jìn)程分別往下繼續(xù)執(zhí)行代碼,進(jìn)入了不同的if分支捆毫。

? ? ? ?如何理解pid在父子進(jìn)程中不同闪湾?

? ? ? ?其實(shí)就相當(dāng)于鏈表,進(jìn)程形成了鏈表绩卤,父進(jìn)程的pid指向了子進(jìn)程的pid途样,因?yàn)樽舆M(jìn)程沒(méi)有子進(jìn)程,所以pid為0濒憋。


? ??????●?寫(xiě)時(shí)復(fù)制

? ? ? ?傳統(tǒng)的fork機(jī)制是何暇,調(diào)用fork時(shí),內(nèi)核會(huì)復(fù)制所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)凛驮,復(fù)制進(jìn)程的頁(yè)表項(xiàng)裆站,然后把父進(jìn)程的地址空間按頁(yè)復(fù)制給子進(jìn)程(非常耗時(shí))。

? ? ? ?現(xiàn)代的fork機(jī)制采用了一種惰性算法的優(yōu)化策略黔夭。

? ? ? ?為了避免復(fù)制時(shí)系統(tǒng)開(kāi)銷(xiāo)宏胯,就盡可能的減少“復(fù)制”操作,當(dāng)多個(gè)進(jìn)程需要讀取他們自己那部分資源的副本時(shí)本姥,并不復(fù)制多個(gè)副本出來(lái)肩袍,而是為每個(gè)進(jìn)程設(shè)定一個(gè)文件指針,讓它們讀取同一個(gè)實(shí)際文件婚惫。

? ? ? ?顯然這樣的方式會(huì)在寫(xiě)入時(shí)產(chǎn)生沖突(類(lèi)似并發(fā))氛赐,于是當(dāng)某個(gè)進(jìn)程想要修改自己的那個(gè)副本時(shí),再去復(fù)制該資源先舷,(只有寫(xiě)入時(shí)才復(fù)制艰管,所以叫寫(xiě)時(shí)復(fù)制)這樣就減少了復(fù)制的頻率。


??聯(lián)合實(shí)例

? ? ? ?在程序中創(chuàng)建一個(gè)子進(jìn)程蒋川,打開(kāi)另一個(gè)應(yīng)用牲芋。


pid_t pid;

pid = fork();

if (pid == -1)

? ? perror("fork");

//子進(jìn)程

if (!pid) {

? ? const char * args[] = {"windlass",NULL};

? ? int ret;

? ? // 參數(shù)以數(shù)組方式傳入

? ? ret = execv("/bin/windlass",args);

? ? if (ret == -1) {

? ? ? ? perror("execv");

? ? ? ? exit(EXIT_FAILURE);

? ? }

}


? ? ? ?上面的程序創(chuàng)建了一個(gè)子進(jìn)程,并且使子進(jìn)程運(yùn)行了/bin/windlas程序捺球。


??終止進(jìn)程

??exit()

? ??????●?函數(shù)原型

void exit (int status)

? ? ? ?該函數(shù)用于終止當(dāng)前的進(jìn)程街图,參數(shù)status只用于標(biāo)識(shí)進(jìn)程的退出狀態(tài),這個(gè)值將會(huì)被傳送給當(dāng)前進(jìn)程的父進(jìn)程用于判斷懒构。

? ? ? ?還有一些其他的終止調(diào)用函數(shù),在此不贅述耘擂。

如果你也很想學(xué)編程胆剧,可以來(lái)我專(zhuān)欄的C語(yǔ)言/C++編程學(xué)習(xí)基地【點(diǎn)擊進(jìn)入】!

還有(源碼,零基礎(chǔ)教程秩霍,項(xiàng)目實(shí)戰(zhàn)教學(xué)視頻)篙悯!帶你入個(gè)門(mén)還是簡(jiǎn)簡(jiǎn)單單啦~

涉及:游戲開(kāi)發(fā)、課程設(shè)計(jì)铃绒、常用軟件開(kāi)發(fā)鸽照、編程基礎(chǔ)知識(shí)、黑客等等...

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颠悬,一起剝皮案震驚了整個(gè)濱河市矮燎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赔癌,老刑警劉巖诞外,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異灾票,居然都是意外死亡峡谊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)刊苍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)既们,“玉大人,你說(shuō)我怎么就攤上這事正什∩吨剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵埠忘,是天一觀的道長(zhǎng)脾拆。 經(jīng)常有香客問(wèn)我,道長(zhǎng)莹妒,這世上最難降的妖魔是什么名船? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮旨怠,結(jié)果婚禮上渠驼,老公的妹妹穿的比我還像新娘。我一直安慰自己鉴腻,他們只是感情好迷扇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著爽哎,像睡著了一般蜓席。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上课锌,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天厨内,我揣著相機(jī)與錄音祈秕,去河邊找鬼。 笑死雏胃,一個(gè)胖子當(dāng)著我的面吹牛请毛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瞭亮,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼方仿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了统翩?” 一聲冷哼從身側(cè)響起仙蚜,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唆缴,沒(méi)想到半個(gè)月后鳍征,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡面徽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年艳丛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趟紊。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡氮双,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出霎匈,到底是詐尸還是另有隱情戴差,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布铛嘱,位于F島的核電站暖释,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏墨吓。R本人自食惡果不足惜球匕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帖烘。 院中可真熱鬧亮曹,春花似錦、人聲如沸秘症。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乡摹。三九已至役耕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聪廉,已是汗流浹背瞬痘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工氏义, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人图云。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像邻邮,于是被迫代替她去往敵國(guó)和親竣况。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355