操作系統(tǒng)接口一

圖片發(fā)自簡(jiǎn)書(shū)App
書(shū)接上文超神之路颤练,言歸正傳,圓規(guī)正傳。

進(jìn)程和內(nèi)存

進(jìn)程有自己的內(nèi)存空間(指令 數(shù)據(jù) 和棧)若贮,翻譯這段話真別扭。操作系統(tǒng)可以在一組需要執(zhí)行的進(jìn)程之間進(jìn)行切換痒留,當(dāng)一個(gè)進(jìn)程沒(méi)有執(zhí)行時(shí)谴麦,系統(tǒng)會(huì)保存進(jìn)程的寄存器狀態(tài),在下一次執(zhí)行的時(shí)候恢復(fù)狀態(tài)伸头。是不是很簡(jiǎn)單匾效,簡(jiǎn)單,你寫(xiě)一個(gè)試試恤磷。內(nèi)核會(huì)給每個(gè)進(jìn)程分配一個(gè)進(jìn)程標(biāo)識(shí)面哼,就是經(jīng)常看到的pid扫步。

利用fork可以創(chuàng)建一個(gè)新的進(jìn)程魔策,這個(gè)是什么意思?

看看fork


int pid = fork();
if(pid > 0){
     printf("parent: child=%d\n", pid);
     pid = wait();
     printf("child %d is done\n", pid);} 
else if(pid == 0){
     printf("child: exiting\n");
     exit();
} else {
    printf("fork error\n");
}

首先父進(jìn)程調(diào)用fork,產(chǎn)生子進(jìn)程河胎,子進(jìn)程擁有和父親相同內(nèi)容的內(nèi)存空間闯袒。最奇怪的就是fork調(diào)用會(huì)返回兩次,所以后面就是兩個(gè)程序了游岳,就像影分身搁吓。在父進(jìn)程里面返回子進(jìn)程的進(jìn)程id,在子進(jìn)程里面返回0(為啥喜歡這樣干吭历,迷惑吧)堕仔。

exit調(diào)用會(huì)終止進(jìn)程,且釋放內(nèi)存和文件資源晌区。wait會(huì)等待子進(jìn)程退出摩骨。

程序的輸出

parent: child=1234// p
child: exiting      //c
parent: child 1234 is done

p和c的順序不是一定的通贞,看誰(shuí)首先獲得調(diào)度,但是最后一句肯定在后面∧瘴澹現(xiàn)在兩個(gè)程序有不同的寄存器和內(nèi)存昌罩,改變一個(gè)變量不會(huì)影響另外一個(gè)。

exec這個(gè)系統(tǒng)調(diào)用灾馒,會(huì)從文件系統(tǒng)中加載一個(gè)可執(zhí)行文件茎用,替換掉當(dāng)前的進(jìn)程內(nèi)存空間。這個(gè)文件需要符合一定的格式睬罗,包含指令轨功,啟動(dòng)地址,和數(shù)據(jù)容达,調(diào)用以后直接執(zhí)行啟動(dòng)命令古涧。


char *argv[3];
argv[0] = "echo";
argv[1] = "hello";
argv[2] = 0;
exec("/bin/echo", argv);
printf("exec error\n");

這兩個(gè)的區(qū)別是一個(gè)復(fù)制父進(jìn)程,一個(gè)替換花盐,是不是有點(diǎn)難以理解羡滑,為啥不新建一個(gè)(如果你也思考了這個(gè)問(wèn)題,那后面就會(huì)有回答)算芯,再做處理柒昏,這可能是進(jìn)程資源創(chuàng)建的問(wèn)題。exec會(huì)分配足夠的內(nèi)存熙揍,如果不夠用昙楚,再進(jìn)行系統(tǒng)調(diào)用分配內(nèi)存。

是不是感覺(jué)獲得了一甲子功力?孩子別傻诈嘿,現(xiàn)在還早堪旧,到現(xiàn)在一切還流于表面,后續(xù)的路還多著奖亚。請(qǐng)不要著急淳梦,耐心一點(diǎn)。

io和文件描述符

文件描述符是一個(gè)小整數(shù)昔字,代表進(jìn)程要讀寫(xiě)的對(duì)象爆袍,這沒(méi)有什么奇怪的,匯編里面也支持讀寫(xiě)文件作郭,在上一節(jié)中陨囊,可以在寄存器里填上值,代表不同的操作夹攒。

這里的文件描述符蜘醋,代表一種抽象的文件,可以是文件咏尝,設(shè)備压语,管道啸罢,都當(dāng)做一種字節(jié)流來(lái)處理。

每個(gè)進(jìn)程都保存這一個(gè)文件資源表格胎食,默認(rèn)從0開(kāi)始扰才,代表輸入,1代表輸出厕怜,2代表錯(cuò)誤衩匣。shell為了實(shí)現(xiàn)重定向(> <)和管道(|),要確保這幾個(gè)總是打開(kāi)的狀態(tài)粥航。

read會(huì)讀取幾個(gè)字節(jié)到buf里面琅捏,返回字節(jié)數(shù),如果沒(méi)有了就返回0躁锡。這里初學(xué)者比較難以理解的就是為啥要buf午绳,一下把文件讀入內(nèi)存不就得了置侍,得到我要的字符串就好了映之。這肯定沒(méi)有考慮到大文件的情況,內(nèi)存放不下的時(shí)候蜡坊,一般測(cè)試者這里只是一個(gè)有幾字節(jié)的小文件而已杠输。剛開(kāi)始嘛,想一下子解決問(wèn)題秕衙,誰(shuí)會(huì)想到用這些奇怪的技巧蠢甲,但是起碼得漲下經(jīng)驗(yàn)吧。write類(lèi)似就不說(shuō)了据忘。

基本的cat實(shí)現(xiàn)(單純用c語(yǔ)言的getchar putchar 也可以實(shí)現(xiàn))


char buf[512];
int n;
for(;;){
   n = read(0, buf, sizeof buf);
   if(n == 0)break;
   if(n < 0){
       fprintf(2, "read error\n");
       exit();
  }
  if(write(1, buf, n) != n){
       fprintf(2, "write error\n");
       exit();
  }
}

注意這里的cat基本不知道從哪里讀鹦牛,往哪里寫(xiě),是文件還是管道勇吊。
還有一點(diǎn)沒(méi)有提的就是曼追,fork和exec調(diào)用都會(huì)保存父進(jìn)程的文件表格,所以借用這些就可以實(shí)現(xiàn)重定向汉规。

cat <input.txt

char *argv[2];
argv[0] = "cat";
argv[1] = 0;
if(fork() == 0) {
close(0);
open("input.txt", O_RDONLY);
exec("cat", argv);
}

因?yàn)樵趀xec->cat后礼殊,進(jìn)程的0文件還是input.txt里面的內(nèi)容,當(dāng)然這次1就成了控制臺(tái)了。

其他

(真是個(gè)好的分類(lèi)针史,什么都可以扔這里晶伦,因?yàn)榈竭@里已經(jīng)寫(xiě)的很累了,讀者肯定也累了啄枕,也不要期望婚陪,一下子理解,因?yàn)槲矣X(jué)得不可能频祝。我會(huì)分出一篇接口二近忙。)

管道利用了一些類(lèi)似的技巧竭业,可以得到期望的文件描述符。
文件系統(tǒng)很值得學(xué)習(xí)的就是路徑的表示方法及舍,是樹(shù)這種數(shù)據(jù)結(jié)構(gòu)一種神來(lái)之筆未辆,樹(shù)真的是一種強(qiáng)大的數(shù)據(jù)結(jié)構(gòu),無(wú)處不在锯玛「拦瘢互聯(lián)網(wǎng)也有這種路徑的表示方法的意思,包括最近rest接口定義攘残。

文件實(shí)現(xiàn)相關(guān)的肯定需要了解磁盤(pán)的結(jié)構(gòu)了拙友,后面再說(shuō)吧,cpu本身就有文件的讀寫(xiě)指令歼郭。這種將各種設(shè)備資源抽象成文件的方法遗契,受到人們的追捧,我也不知道好不好病曾。

總之里面shell展示了系統(tǒng)調(diào)用(如wait close等)的靈活組裝方式牍蜂,真可以感嘆一些這些精巧是如何想到的,起碼對(duì)于我來(lái)說(shuō)很不自然泰涂。

總結(jié)

一些目前學(xué)到的東西鲫竞,以便更好的前行。首先是一些超凡脫俗的名詞逼蒙,看文章首的接口圖片从绘,還有一些沒(méi)有講到的自己查閱。大師是命名高手是牢,一個(gè)詞匯代表了太多的東西僵井,絕逼是抽象派的。

良好的接口定義驳棱,可以讓系統(tǒng)容易實(shí)現(xiàn)批什,且擁有靈活的組合方式,畢竟接口定義了這個(gè)操作系統(tǒng)蹈胡,你說(shuō)牛不牛渊季。Java有jnr實(shí)現(xiàn)了一系列底層的接口,js都可以加載操作系統(tǒng)了罚渐。如今docker和openstack如日中天却汉,你說(shuō)不學(xué)點(diǎn)操作系統(tǒng)對(duì)得起誰(shuí)?接口說(shuō)完了,該說(shuō)一下實(shí)現(xiàn)了荷并,對(duì)不起這篇文章已經(jīng)太長(zhǎng)了合砂,期待下一篇吧,下次要火力全開(kāi)了源织。

這系列教程翩伪,是在閱讀一些書(shū)籍和代碼過(guò)程的記錄微猖,基本是xv6的翻譯了(暈吧) 。如果你讀到更好的文章推薦給我缘屹,我不寫(xiě)了凛剥。歡迎閱讀我的其它文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末轻姿,一起剝皮案震驚了整個(gè)濱河市犁珠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌互亮,老刑警劉巖犁享,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異豹休,居然都是意外死亡炊昆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)威根,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)凤巨,“玉大人,你說(shuō)我怎么就攤上這事医窿“跛Γ” “怎么了炊林?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵姥卢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我渣聚,道長(zhǎng)独榴,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任奕枝,我火速辦了婚禮棺榔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘隘道。我一直安慰自己症歇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布谭梗。 她就那樣靜靜地躺著忘晤,像睡著了一般身冀。 火紅的嫁衣襯著肌膚如雪寄摆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,829評(píng)論 1 290
  • 那天短纵,我揣著相機(jī)與錄音远舅,去河邊找鬼闰蛔。 笑死痕钢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的序六。 我是一名探鬼主播任连,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼例诀!你這毒婦竟也來(lái)了课梳?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤余佃,失蹤者是張志新(化名)和其女友劉穎暮刃,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體爆土,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椭懊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了步势。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氧猬。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖坏瘩,靈堂內(nèi)的尸體忽然破棺而出盅抚,到底是詐尸還是另有隱情,我是刑警寧澤倔矾,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布妄均,位于F島的核電站,受9級(jí)特大地震影響哪自,放射性物質(zhì)發(fā)生泄漏丰包。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一壤巷、第九天 我趴在偏房一處隱蔽的房頂上張望邑彪。 院中可真熱鬧,春花似錦胧华、人聲如沸寄症。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)有巧。三九已至,卻和暖如春铅忿,著一層夾襖步出監(jiān)牢的瞬間剪决,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柑潦,地道東北人享言。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像渗鬼,于是被迫代替她去往敵國(guó)和親览露。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容