?1. 硬鏈接和軟連接區(qū)別 ?
硬連接-------指通過索引節(jié)點(diǎn)來進(jìn)行連接缺亮。在Linux的文件系統(tǒng)中曙砂,保存在磁盤分區(qū)中的文件不管是什么類型都給它分配一個(gè)編號(hào)清笨,稱為索引節(jié)點(diǎn)號(hào)(Inode Index)只搁。在Linux中突倍,多個(gè)文件名指向同一索引節(jié)點(diǎn)是存在的。比如:A是B的硬鏈接(A和B都是文件名)穴吹,則A的目錄項(xiàng)中的inode節(jié)點(diǎn)號(hào)與B的目錄項(xiàng)中的inode節(jié)點(diǎn)號(hào)相同幽勒,即一個(gè)inode節(jié)點(diǎn)對(duì)應(yīng)兩個(gè)不同的文件名,兩個(gè)文件名指向同一個(gè)inode節(jié)點(diǎn)港令,A和B對(duì)文件系統(tǒng)來說是完全平等的啥容。刪除其中任何一個(gè)都不會(huì)影響另外一個(gè)的訪問。硬連接的作用是允許一個(gè)文件擁有多個(gè)有效路徑名顷霹,這樣用戶就可以建立硬連接到重要文件咪惠,以防止“誤刪”的功能。只刪除一個(gè)連接并不影響索引節(jié)點(diǎn)本身和其它的連接泼返,只有當(dāng)最后一個(gè)連接被刪除后硝逢,文件的數(shù)據(jù)塊及目錄的連接才會(huì)被釋放。也就是說绅喉,文件真正刪除的條件是與之相關(guān)的所有硬連接文件均被刪除,如果我們刪除硬鏈接文件的源文件叫乌,硬鏈接文件仍然存在柴罐,而且保留了原有的內(nèi)容。
軟鏈接--------又叫符號(hào)鏈接憨奸,有點(diǎn)類似于Windows的快捷方式革屠。它實(shí)際上是一個(gè)特殊的文件。在符號(hào)連接中排宰,文件實(shí)際上是一個(gè)文本文件似芝,其中包含的有另一文件的位置信息。比如:A是B的軟鏈接(A和B都是文件名)板甘,A的目錄項(xiàng)中的inode節(jié)點(diǎn)號(hào)與B的目錄項(xiàng)中的inode節(jié)點(diǎn)號(hào)不相同党瓮,A和B指向的是兩個(gè)不同的inode盔憨,繼而指向兩塊不同的數(shù)據(jù)塊紊搪。但是A的數(shù)據(jù)塊中存放的只是B的路徑名(可以根據(jù)這個(gè)找到B的目錄項(xiàng))试伙。A和B之間是“主從”關(guān)系楞遏,如果B被刪除了冰木,A仍然存在(因?yàn)閮蓚€(gè)是不同的文件)岁忘,但指向的是一個(gè)無效的鏈接决侈。
附加:? linux系統(tǒng)下的文件包括inode結(jié)構(gòu)和data兩部分史飞,其中inode結(jié)構(gòu)中有兩個(gè)引用計(jì)數(shù)icount和inlink猫妙,前者記錄該文件當(dāng)前的使用者數(shù)量瓷翻,后者記錄該文件的介質(zhì)鏈接數(shù)量,即前者針對(duì)內(nèi)存,后者針對(duì)硬盤齐帚,只有這兩個(gè)引用計(jì)數(shù)值都為0的情況下元践,data的刪除才真正進(jìn)行。
2. kill用法童谒,某個(gè)進(jìn)程殺不掉的原因(進(jìn)入內(nèi)核態(tài)单旁,忽略kill信號(hào))
(1)kill用法
先用查看進(jìn)程id命令 ? ps -ef? , 然后用殺死進(jìn)程 ?? kill -9 PID
(2).進(jìn)程殺不掉的原因:
(1)進(jìn)程已經(jīng)成為僵尸進(jìn)程饥伊,當(dāng)它的父進(jìn)程將它回收或?qū)⑺母高M(jìn)程kill掉象浑,此時(shí)進(jìn)程已經(jīng)釋放所有的資源,但是沒有被父進(jìn)程釋放(所以僵尸進(jìn)程的存在不會(huì)影響系統(tǒng)性能)琅豆。僵尸進(jìn)程要等到父進(jìn)程結(jié)束愉豺,或者重啟系統(tǒng)才可以被釋放。
(2)進(jìn)程正處在內(nèi)核狀態(tài)中茫因,Linux進(jìn)程運(yùn)行時(shí)分內(nèi)核和用戶兩種狀態(tài)蚪拦,當(dāng)進(jìn)程進(jìn)入內(nèi)核狀態(tài)后,會(huì)屏蔽所有信號(hào)冻押,包括SIGKIL驰贷,所以這個(gè)時(shí)候kill -9也變得無效了。
? 3.系統(tǒng)管理命令(如查看內(nèi)存使用洛巢、網(wǎng)絡(luò)情況)
(1) df? 和? df -hl ?用來檢查文件系統(tǒng)的磁盤空間占用情況括袒,使用權(quán)限是所有用戶
(2) top, ? top命令用來顯示執(zhí)行中的程序進(jìn)程,使用權(quán)限是所有用戶(想對(duì)進(jìn)程進(jìn)行實(shí)時(shí)監(jiān)控應(yīng)該用top命令)
(3)?free,? free命令用來顯示內(nèi)存的使用情況稿茉,使用權(quán)限是所有用戶
(4)?lp,? lp是打印文件的命令锹锰,使用權(quán)限是所有用戶
(5)?useradd, ? useradd命令用來建立用戶帳號(hào)和創(chuàng)建用戶的起始目錄,使用權(quán)限是超級(jí)用戶
(6)? kill 殺死進(jìn)程
(7)ps -ef? 查看進(jìn)程完整信息(PS顯示的是進(jìn)程瞬間狀態(tài)漓库,不連續(xù)) ? ? ? ? ? ps -aux列出目前所有正在內(nèi)存中的進(jìn)程信息
(8)netstat? 查看網(wǎng)絡(luò)狀態(tài)
?4.管道命令 | ??
管道命令操作符是:”|”,它只能處理經(jīng)由前面一個(gè)指令傳出的正確輸出信息恃慧,對(duì)錯(cuò)誤信息信息沒有直接處理能力。然后渺蒿,傳遞給下一個(gè)命令痢士,作為標(biāo)準(zhǔn)的輸入.
舉例: logcat | grep? "wakeupcount"
5.? grep的使用,一定要掌握蘸嘶,每次都會(huì)問在文件中查找
grep - [ option ]
-c:僅僅輸出匹配行的計(jì)數(shù)良瞧。
-I:不區(qū)分大 小寫(僅僅適用于單字符)。
-h(huán):查詢多文件時(shí)不顯示文件名稱训唱。
-l:查詢多文件時(shí)僅僅輸出包括匹配字符的文件名稱褥蚯。
-n:顯示匹配行及 行號(hào)。
-s:不顯示不存在或無匹配文本的錯(cuò)誤信息况增。
-v:顯示不包括匹配文本的全部行赞庶。
?6. find命令?
在/home目錄下查找以.txt結(jié)尾的文件名: ? ? ?? find /home -name "*.txt"
在/home目錄下查找以.txt結(jié)尾的文件名,忽略大小寫: ? ? find /home -iname "*.txt"
匹配文件路徑或者文件: ? ? ? find /usr/-path"*local*"
基于正則表達(dá)式匹配文件路徑: ? ? ? ?? find .-regex".*\(\.txt\|\.pdf\)$"
?7. awk使用?
(1) 使用方法
awk '{pattern + action}' {filenames}
盡管操作可能會(huì)很復(fù)雜,但語法總是這樣,其中 pattern 表示 AWK 在數(shù)據(jù)中查找的內(nèi)容歧强,而 action 是在找到匹配內(nèi)容時(shí)所執(zhí)行的一系列命令澜薄。花括號(hào)({})不需要在程序中始終出現(xiàn)摊册,但它們用于根據(jù)特定的模式對(duì)一系列指令進(jìn)行分組肤京。 pattern就是要表示的正則表達(dá)式,用斜杠括起來茅特。
awk語言的最基本功能是在文件或者字符串中基于指定規(guī)則瀏覽和抽取信息忘分,awk抽取信息后,才能進(jìn)行其他文本操作白修。完整的awk腳本通常用來格式化文本文件中的信息妒峦。
通常,awk是以文件的一行為處理單位的兵睛。awk每接收文件的一行肯骇,然后執(zhí)行相應(yīng)的命令,來處理文本祖很。
(2) 調(diào)用awk方法
1).命令行方式
awk [-F? field-separator]? 'commands'? input-file(s)
其中笛丙,commands 是真正awk命令,[-F域分隔符]是可選的突琳。 input-file(s) 是待處理的文件若债。
在awk中,文件的每一行中拆融,由域分隔符分開的每一項(xiàng)稱為一個(gè)域。通常啊终,在不指名-F域分隔符的情況下镜豹,默認(rèn)的域分隔符是空格。
2).shell腳本方式
將所有的awk命令插入一個(gè)文件蓝牲,并使awk程序可執(zhí)行趟脂,然后awk命令解釋器作為腳本的首行,一遍通過鍵入腳本名稱來調(diào)用例衍, ? ?? ./shell_awk.sh 直接執(zhí)行
?相當(dāng)于shell腳本首行的:#!/bin/sh ? 要換成:#!/bin/awk
3).將所有的awk命令輸入一個(gè)單獨(dú)文件昔期,然后調(diào)用:
awk -f awk-script-file input-file(s)
其中,-f? 選項(xiàng)加載awk-script-file中的awk腳本佛玄,input-file(s)跟上面的是一樣的硼一。
8. linux內(nèi)核中的Timer 定時(shí)器機(jī)制
? ? ? ? 定時(shí)器是Linux提供的一種定時(shí)服務(wù)的機(jī)制。它在某個(gè)特定的時(shí)間喚醒某個(gè)進(jìn)程梦抢,來做一些工作般贼。系統(tǒng)定時(shí)器能以可編程的頻率中斷處理,這一中斷叫做軟中斷。此頻率即為每秒的定時(shí)器節(jié)拍數(shù)HZ哼蛆。HZ的越大蕊梧,說明定時(shí)器節(jié)拍越小,線程調(diào)度的準(zhǔn)確性會(huì)越高腮介。但HZ設(shè)得過大肥矢,對(duì)一個(gè)系統(tǒng)來說并不好,會(huì)導(dǎo)CPU開銷過大叠洗,反而造成任務(wù)調(diào)度效率降低甘改。jiffies 變量記錄系統(tǒng)啟動(dòng)以來,系統(tǒng)定時(shí)器已經(jīng)觸發(fā)的次數(shù)惕味。也就是說每過一秒jiffies的增量為HZ
9. 使用過的 shell 命令
cp , mv , rm , mkdir , touch , pwd , cd? , ls , top , cat , tail , less , df , du , man , find , kill , sudo , cat
10. 使用過的 vim 命令
???????wq!, dd , dw , yy , p , i , %s/old/new/g , /abc 向后搜索字符串a(chǎn)bc 楼誓, ?abc向前搜索字符串a(chǎn)bc
11. gdb?
? 一. gdb命令
(1)啟動(dòng)gdb 的命令 ?? gdb? a.out ? ? (2)獲得幫助命令 (gdb)help
?(3)? 查看程序源代碼? (gdb) list ? ?? (4)從文件頭部向尾部搜索源代碼 ? ? (gdb)? search? 要匹配的代碼?
(5)設(shè)置斷點(diǎn) ? (gdb)b / break? 行數(shù) ? ? (6)清除當(dāng)前所在行的斷點(diǎn) ?(gdb) clear
(7)從頭運(yùn)行程序至第一個(gè)斷點(diǎn) (gdb) r / run ? ?
? (8) 單步執(zhí)行(遇到函數(shù)調(diào)用的時(shí)候不會(huì)進(jìn)入函數(shù)體內(nèi)部) (gdb) n/next
? (9) 單步執(zhí)行(遇到函數(shù)調(diào)用的時(shí)候會(huì)進(jìn)入函數(shù)體內(nèi)部) (gdb) s / step
(10)從當(dāng)前行繼續(xù)運(yùn)行程序至下一個(gè)斷點(diǎn)? (gdb)continue
(11)退出gdb ? ? (gdb) quit
二.? gdb如何傳參數(shù)名挥?gdb怎么調(diào)試疟羹?
gdb調(diào)試 ? linux下如何使用gdb調(diào)試 - bu_想 - 博客園
(1)在使用gdb調(diào)試C/C++程序前,需要用gcc -g test.c -o test(-g選項(xiàng)告訴gcc在編譯程序時(shí)加入調(diào)試信息禀倔,-o選項(xiàng)用來生成輸出的文件名榄融,沒有-o選項(xiàng)的話就默認(rèn)輸出a.out文件名,有的話就輸出我們自己設(shè)的test救湖,但是自己設(shè)的文件名不能和原文件名一樣)? 命令生成帶有調(diào)試信息的可執(zhí)行程序愧杯,否則看到的將是一堆匯編代碼。比如這個(gè)命令生成的是 test文件(如果不加-o選項(xiàng)生成的就是? a.out? 文件)鞋既。
(2)接下來可以這樣進(jìn)入測(cè)試:gdb -q ? a.out? (加上-q選項(xiàng)去除輸出來的gdb的一些版本信息說明之類說明)
(3)使用(gdb)list? 來查看程序的源代碼力九,著通常是調(diào)試程序要做的第一件事情;list只能按順序給出程序源代碼邑闺,但是這樣其實(shí)有時(shí)候不方便跌前,為了定位到某條特定的語句,可以使用? (gdb) search +要找的代碼?
? 感覺第6行代碼可能有點(diǎn)問題陡舅,現(xiàn)在就需要我就需要設(shè)置一個(gè)斷點(diǎn)抵乓,讓程序停在第6行之前。
想看下設(shè)置的斷點(diǎn)信息靶衍,可以使用(gdb)info breakpoints命令灾炭。
如果不需要斷點(diǎn)了,可以用(gdb)disable 1? (1是斷點(diǎn)的編號(hào)颅眶,不是行號(hào))使得斷點(diǎn)失效
? ? ? ? ? ? ? ? ? ? ? ?? 或者(gdb) clear? 1 ?? 直接刪除該斷點(diǎn)1蜈出。(如果沒有斷點(diǎn)編號(hào)參數(shù)的話,就是刪除當(dāng)前行的斷點(diǎn))
? ? ? ? ? ? ? ?? 如果? (gdb)delete ? 則刪除全部斷點(diǎn)
(4)用 (gdb)run? 開始運(yùn)行; ?
?用(gdb)n / next ? 單步執(zhí)行(遇到函數(shù)調(diào)用的時(shí)候不會(huì)進(jìn)入函數(shù)體內(nèi)部), ? 用(gdb) s / step遇到函數(shù)調(diào)用的時(shí)候會(huì)進(jìn)入函數(shù)體內(nèi)部) ;
用(gdb)continue? 指導(dǎo)gdb從當(dāng)前行繼續(xù)運(yùn)行至下一個(gè)斷點(diǎn) ?
(5)用 (gdb)quit? 退出gdb調(diào)試; ?
12. gcc常用選項(xiàng)總結(jié)
(1)常規(guī)選項(xiàng):
-o選項(xiàng)帚呼,(小o)指定輸出文件名 ? ? ? ? ? ? ? ? -c選項(xiàng)掏缎,只編譯皱蹦,不匯編連接
-S選項(xiàng),產(chǎn)生匯編源文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ?? -E選項(xiàng)眷蜈,預(yù)處理C源文件
(2)優(yōu)化選項(xiàng)
-O選項(xiàng)沪哺,基本優(yōu)化 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? -O2選項(xiàng),最大優(yōu)化
(3)調(diào)試選項(xiàng)
-g選項(xiàng)酌儒,產(chǎn)生供gdb調(diào)試用的可執(zhí)行文件 ? ? ? -pg選項(xiàng)辜妓,產(chǎn)生供gprof剖析用的可執(zhí)行文件
13.? I/O多路復(fù)用之---------select、poll和epoll
select:? IO多路復(fù)用之select總結(jié) - Anker's Blog - 博客園
poll: ?? IO多路復(fù)用之poll總結(jié) - Anker's Blog - 博客園
epoll:? IO多路復(fù)用之epoll總結(jié) - Anker's Blog - 博客園
I/O多路復(fù)用:I/O多路復(fù)用就通過一種機(jī)制忌怎,可以監(jiān)視多個(gè)文件描述符籍滴,一旦某個(gè)描述文件符就緒(一般是讀就緒或者寫就緒),能夠通知程序進(jìn)行相應(yīng)的讀寫操作榴啸。
?? 基本思想是:先構(gòu)造一張有關(guān)文件描述符的表孽惰,然后調(diào)用相應(yīng)函數(shù),當(dāng)這些文件描述符中的一個(gè)或多個(gè)已經(jīng)準(zhǔn)備好進(jìn)行I/O時(shí)函數(shù)才返回鸥印,函數(shù)返回時(shí)告訴進(jìn)程哪個(gè)描述符已經(jīng)就緒可以進(jìn)行I/O操作了勋功。
IO多路復(fù)用適用如下場(chǎng)合:
(1)當(dāng)客戶處理多個(gè)描述字時(shí)(一般是交互式輸入和網(wǎng)絡(luò)套接口)库说,必須使用I/O復(fù)用狂鞋。
(2)當(dāng)一個(gè)客戶同時(shí)處理多個(gè)套接口時(shí)潜的,而這種情況是可能的骚揍,但很少出現(xiàn)。
病(3)如果一個(gè)TCP服務(wù)器既要處理監(jiān)聽套接口信不,又要處理已連接套接口,一般也要用到I/O復(fù)用亡呵。
』肴(4)如果一個(gè)服務(wù)器即要處理TCP,又要處理UDP政己,一般要使用I/O復(fù)用。
√统睢(5)如果一個(gè)服務(wù)器要處理多個(gè)服務(wù)或多個(gè)協(xié)議歇由,一般要使用I/O復(fù)用。
與多進(jìn)程和多線程技術(shù)相比果港,I/O多路復(fù)用技術(shù)的最大優(yōu)勢(shì)是系統(tǒng)開銷小沦泌,系統(tǒng)不必創(chuàng)建進(jìn)程/線程,也不必維護(hù)這些進(jìn)程/線程辛掠,從而大大減小了系統(tǒng)的開銷谢谦。
(1)select: ?I/O多路復(fù)用之select - zengzy - 博客園
select:? 允許進(jìn)程監(jiān)聽多個(gè)文件描述符組成的一個(gè)集合释牺,它會(huì)一直阻塞等待,直到集合中有一個(gè)或多個(gè)文件描述符(或者說資源)準(zhǔn)備就緒回挽,那么函數(shù)會(huì)立刻返回并告訴進(jìn)程哪個(gè)文件描述符已經(jīng)準(zhǔn)備好了没咙。(注意:select 函數(shù)執(zhí)行完畢后,會(huì)清除掉集合中沒有準(zhǔn)備就緒的文件描述符)
具體解釋來說就是-----------當(dāng)應(yīng)用程序調(diào)用select() 函數(shù), 內(nèi)核就會(huì)相應(yīng)調(diào)用 poll_wait()千劈, 把當(dāng)前應(yīng)用程序進(jìn)程添加到相應(yīng)設(shè)備的等待隊(duì)列上祭刚,然后將該應(yīng)用程序進(jìn)程設(shè)置為睡眠狀態(tài)。直到該設(shè)備上的數(shù)據(jù)可以獲取墙牌,然后調(diào)用wake_up()喚醒該應(yīng)用程序進(jìn)程涡驮。select每次輪詢都會(huì)遍歷所有文件描述符fd。
select本質(zhì)上是通過設(shè)置或者檢查存放fd標(biāo)志位(fd就是文件描述符file descriptor)的數(shù)據(jù)結(jié)構(gòu)來進(jìn)行下一步處理喜滨。它通過一個(gè)select()系統(tǒng)調(diào)用來監(jiān)視多個(gè)文件描述符的數(shù)組捉捅;
這樣所帶來的缺點(diǎn)是:
1)、 單個(gè)進(jìn)程可監(jiān)視的fd數(shù)量被限制(可監(jiān)聽的fd數(shù)量為maxfd)虽风,即能監(jiān)聽端口的大小有限棒口。
????? 一般來說這個(gè)數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大,具體數(shù)目可以cat /proc/sys/fs/file-max察看焰情。32位機(jī)默認(rèn)是1024個(gè)陌凳。64位機(jī)默認(rèn)是2048.
2)、 對(duì)socket進(jìn)行掃描時(shí)是線性掃描内舟,即采用輪詢的方法合敦,效率較低:
?????? 當(dāng)套接字比較多的時(shí)候,每次select()都要通過遍歷FD_SETSIZE個(gè)Socket來完成調(diào)度,不管哪個(gè)Socket是活躍的,都遍歷一遍验游。這會(huì)浪費(fèi)很多CPU時(shí)間充岛。如果能給套接字注冊(cè)某個(gè)回調(diào)函數(shù),當(dāng)他們活躍時(shí)耕蝉,自動(dòng)完成相關(guān)操作崔梗,那就避免了輪詢,這正是epoll與kqueue做的垒在。
3)蒜魄、需要維護(hù)一個(gè)用來存放大量fd的數(shù)據(jù)結(jié)構(gòu),這樣會(huì)使得用戶空間和內(nèi)核空間在傳遞該結(jié)構(gòu)時(shí)復(fù)制開銷大
(? 注釋:再?gòu)?qiáng)調(diào)一下fd標(biāo)志位场躯,每個(gè)進(jìn)程的結(jié)構(gòu)里面有一個(gè)列表谈为,這個(gè)列表包含了進(jìn)程中所有被打開的文件(socket也是文件的一種)的信息。列表里面每一個(gè)文件占用一個(gè)槽踢关,而fd就是指的該文件槽的位置伞鲫。一般來說進(jìn)程中手工打開文件時(shí)第一個(gè)fd 為 3, 而0,1,2 都是被系統(tǒng)使用的签舞。其中 0 是 stdin秕脓,也就是標(biāo)準(zhǔn)輸入柒瓣,例如從鍵盤輸入或者unix下面的pipe。1是stdout吠架,也就是標(biāo)準(zhǔn)輸出芙贫,一般來說是屏幕,如果有管道的話就發(fā)到管道里面诵肛, ? 2是stderr屹培,就是錯(cuò)誤輸出。)
Linux環(huán)境編程之文件I/O(一):文件描述符 - 小賤6 - 博客園
文件描述符:內(nèi)核(kernel)利用文件描述符(file descriptor)來訪問文件怔檩。文件描述符是非負(fù)整數(shù)褪秀。打開現(xiàn)存文件或新建文件時(shí),內(nèi)核會(huì)返回一個(gè)文件描述符薛训。讀寫文件也需要使用文件描述符來指定待讀寫的文件媒吗。文件描述符在形式上是一個(gè)非負(fù)整數(shù)。實(shí)際上乙埃,它是一個(gè)索引值(可以理解為數(shù)組下標(biāo))闸英,指向內(nèi)核為每一個(gè)進(jìn)程所維護(hù)的該進(jìn)程打開文件的記錄表。當(dāng)程序打開一個(gè)現(xiàn)有文件或者創(chuàng)建一個(gè)新文件時(shí)介袜,內(nèi)核向進(jìn)程返回一個(gè)文件描述符甫何。在程序設(shè)計(jì)中,一些涉及底層的程序編寫往往會(huì)圍繞著文件描述符展開遇伞。但是文件描述符這一概念往往只適用于UNIX辙喂、Linux這樣的操作系統(tǒng)。當(dāng)我們想要用read鸠珠、write等系統(tǒng)調(diào)用對(duì)文件進(jìn)行讀寫等操作之前巍耗,必須用open或create系統(tǒng)調(diào)用得到文件的描述符。?
文件描述表:每個(gè)進(jìn)程在Linux內(nèi)核中都有一個(gè)task_struct結(jié)構(gòu)體(就是PCB)來維護(hù)進(jìn)程的相關(guān)信息渐排,稱為進(jìn)程描述符炬太。PCB中有文件描述符表(有個(gè)指針成員(struct files_struct *files)指向files_struct結(jié)構(gòu)體),文件描述符表是個(gè)數(shù)組結(jié)構(gòu)驯耻,其中的每個(gè)表項(xiàng)包含一個(gè)指向已打開的文件的指針(可以理解為數(shù)組里面存的是指針)亲族。用戶不能直接訪問內(nèi)核中的文件描述符表,而只能使用文件描述符表的索引(即數(shù)組下標(biāo)0,1,2,3.......)可缚,即文件描述符孽水。
文件描述符、文件指針城看、文件路徑三者之間的關(guān)系:
(1)首先,文件描述符fd一般是在Unix系統(tǒng)或類Unix系統(tǒng)中的概念杏慰,它其實(shí)是一個(gè)整數(shù)测柠,用它可以來獲取文件描述符表中的某個(gè)已打開文件炼鞠。
(2)文件指針FILE是C庫中的概念,它不單單在Linux系統(tǒng)中轰胁,在windows中也會(huì)出現(xiàn)谒主,文件指針指向進(jìn)程中用戶區(qū)中一個(gè)被稱為FILE結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu),該FILE結(jié)構(gòu)包括一個(gè)緩沖區(qū)和一個(gè)文件描述符赃阀。FILE中包含fd信息霎肯,還包含IO緩沖,所以FILE比fd更適合跨平臺(tái)榛斯。它們之間可以利用fdopen函數(shù)和fileno函數(shù)互相轉(zhuǎn)化观游。
FILE *fdopen(int fd, const char *mode);
int fileno(FILE *stream);
(3)文件路徑就是文件所在路徑,通常驮俗,我們就是通過文件路徑得到具體文件懂缕,從而得到文件描述符、文件指針的王凑。
(2)poll:
? ? ? ? poll本質(zhì)上和select沒有區(qū)別搪柑,它將用戶傳入的文件描述符表拷貝到內(nèi)核空間,然后查詢每個(gè)fd對(duì)應(yīng)的設(shè)備狀態(tài)索烹,如果設(shè)備就緒則在設(shè)備等待隊(duì)列中將該進(jìn)程加入工碾,并繼續(xù)遍歷;如果遍歷完所有fd后沒有發(fā)現(xiàn)就緒設(shè)備百姓,則掛起當(dāng)前進(jìn)程渊额,直到設(shè)備就緒或者主動(dòng)超時(shí)該進(jìn)程才再次被喚醒,被喚醒后它又要再次遍歷fd瓣戚。這個(gè)過程經(jīng)歷了多次無謂的遍歷端圈。
在select/poll時(shí)代,服務(wù)器進(jìn)程每次都把這100萬個(gè)連接告訴操作系統(tǒng)(從用戶態(tài)復(fù)制句柄數(shù)據(jù)結(jié)構(gòu)到內(nèi)核態(tài))子库,讓操作系統(tǒng)內(nèi)核去查詢這些套接字上是否有事件發(fā)生舱权,輪詢完后,再將句柄數(shù)據(jù)復(fù)制到用戶態(tài)仑嗅,讓服務(wù)器應(yīng)用程序輪詢處理已發(fā)生的網(wǎng)絡(luò)事件宴倍,這一過程資源消耗較大,因此仓技,select/poll一般只能處理幾千的并發(fā)連接鸵贬。
它沒有最大連接數(shù)的限制,原因是它是基于鏈表來存儲(chǔ)的脖捻,但是同樣有一個(gè)缺點(diǎn):
1阔逼、大量的fd的數(shù)組被整體復(fù)制于用戶態(tài)和內(nèi)核地址空間之間,而不管這樣的復(fù)制是不是有意義地沮。???????????????????
2嗜浮、poll還有一個(gè)特點(diǎn)是“水平觸發(fā)”羡亩,如果報(bào)告了fd后,沒有被處理危融,那么下次poll時(shí)會(huì)再次報(bào)告該fd畏铆。
(3)epoll: ?
? ? ? 它能顯著提高程序在大量并發(fā)連接中只有少量活躍的情況下的系統(tǒng)CPU利用率。另一點(diǎn)原因就是獲取事件的時(shí)候吉殃,它無須遍歷整個(gè)被偵聽的描述符集辞居,只要遍歷那些被內(nèi)核IO事件異步喚醒而加入就緒鏈表的描述符集合就行了
與select相比,epoll分清了頻繁調(diào)用和不頻繁調(diào)用的操作蛋勺。例如瓦灶,epoll_ctrl是不太頻繁調(diào)用的,而epoll_wait是非常頻繁調(diào)用的迫卢。這時(shí)倚搬,epoll_wait卻幾乎沒有入?yún)ⅲ@比select的效率高出一大截乾蛤,而且每界,它也不會(huì)隨著并發(fā)連接的增加使得入?yún)⒃桨l(fā)多起來,導(dǎo)致內(nèi)核執(zhí)行效率下降家卖。
epoll有EPOLLLT和EPOLLET兩種觸發(fā)模式眨层,LT是默認(rèn)的模式,ET是“高速”模式上荡。
(4)epoll為什么要有EPOLLET? (ET) 觸發(fā)模式趴樱?徹底學(xué)會(huì)使用epoll(一)——ET模式實(shí)現(xiàn)分析-lvyilong316-ChinaUnix博客
如果采用EPOLLLT (LT) 模式的話,系統(tǒng)中一旦有大量你不需要讀寫的就緒文件描述符酪捡,這些就緒文件描述符都會(huì)被放入到ready list中去叁征,每次調(diào)用epoll_wait都會(huì)返回 fd 并通知給用戶空間;? 這樣會(huì)大大降低處理程序檢索自己關(guān)心的就緒文件描述符的效率.逛薇。而采用EPOLLET這種邊沿觸發(fā)模式的話捺疼,當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時(shí),epoll_wait()會(huì)通知處理程序去讀寫永罚。如果這次沒有把數(shù)據(jù)全部讀寫完(如讀寫緩沖區(qū)太小)啤呼,那么下次調(diào)用epoll_wait()時(shí),它不會(huì)返回并通知進(jìn)程呢袱,也就是它只會(huì)通知一次官扣,直到該文件描述符上出現(xiàn)第二次可讀寫事件才會(huì)返回fd并通知進(jìn)程!P吒!鱼蝉!這種模式比水平觸發(fā)效率高养涮,系統(tǒng)不會(huì)充斥大量你不關(guān)心的就緒文件描述符
(5)epoll的優(yōu)點(diǎn):
1赶促、沒有最大并發(fā)連接的限制,能打開的FD的上限遠(yuǎn)大于1024(1G的內(nèi)存上能監(jiān)聽約10萬個(gè)端口)挟炬;
2鸥滨、效率提升,不是輪詢的方式谤祖,不會(huì)隨著FD數(shù)目的增加效率下降婿滓。只有活躍可用的FD才會(huì)調(diào)用callback函數(shù);
即Epoll最大的優(yōu)點(diǎn)就在于它只管你“活躍”的連接粥喜,而跟連接總數(shù)無關(guān)凸主,因此在實(shí)際的網(wǎng)絡(luò)環(huán)境中,Epoll的效率就會(huì)遠(yuǎn)遠(yuǎn)高于select和poll额湘。
3卿吐、另一點(diǎn)原因就是獲取事件的時(shí)候,它無須遍歷整個(gè)被偵聽的描述符集锋华,只要遍歷那些被內(nèi)核IO事件異步喚醒而加入rdlist就緒鏈表中的描述符集合就行了
4嗡官、 內(nèi)存拷貝,利用mmap()文件映射內(nèi)存加速與內(nèi)核空間的消息傳遞毯焕;即epoll使用mmap減少?gòu)?fù)制開銷衍腥。
(6)select、poll纳猫、epoll 區(qū)別總結(jié):(最重要的)
select婆咸、poll、epoll之間的區(qū)別總結(jié)[整理] - Anker's Blog - 博客園
1)支持一個(gè)進(jìn)程所能打開的最大連接數(shù)
select:?jiǎn)蝹€(gè)進(jìn)程所能打開的最大連接數(shù)有FD_SETSIZE宏定義物遇,其大小是32個(gè)整數(shù)的大泄猿稹(在32位的機(jī)器上,大小就是3232询兴,同理64位機(jī)器上FD_SETSIZE為3264)乃沙,當(dāng)然我們可以對(duì)進(jìn)行修改,然后重新編譯內(nèi)核诗舰,但是性能可能會(huì)受到影響警儒,這需要進(jìn)一步的測(cè)試。
poll:poll本質(zhì)上和select沒有區(qū)別,但是它沒有最大連接數(shù)的限制蜀铲,原因是它是基于鏈表來存儲(chǔ)的
epoll:雖然連接數(shù)有上限边琉,但是很大,1G內(nèi)存的機(jī)器上可以打開10萬左右的連接记劝,2G內(nèi)存的機(jī)器可以打開20萬左右的連接
2)FD劇增后帶來的IO效率問題
select:因?yàn)槊看握{(diào)用時(shí)都會(huì)對(duì)連接進(jìn)行線性遍歷变姨,所以隨著FD的增加會(huì)造成遍歷速度慢的“線性下降性能問題”。
poll:同上
epoll:因?yàn)閑poll內(nèi)核中實(shí)現(xiàn)是根據(jù)每個(gè)fd上的callback函數(shù)來實(shí)現(xiàn)的厌丑,只有活躍的socket才會(huì)主動(dòng)調(diào)用callback定欧,所以在活躍socket較少的情況下,使用epoll沒有前面兩者的線性下降的性能問題怒竿,但是所有socket都很活躍的情況下砍鸠,可能會(huì)有性能問題。
3) 消息傳遞方式
select:內(nèi)核需要將消息傳遞到用戶空間耕驰,都需要內(nèi)核拷貝動(dòng)作
poll:同上
epoll:epoll通過內(nèi)核和用戶空間共享一塊內(nèi)存來實(shí)現(xiàn)的爷辱。
總結(jié):
綜上,在選擇select朦肘,poll饭弓,epoll時(shí)要根據(jù)具體的使用場(chǎng)合以及這三種方式的自身特點(diǎn)。
1厚骗、表面上看epoll的性能最好示启,但是在連接數(shù)少并且連接都十分活躍的情況下,select和poll的性能可能比epoll好领舰,畢竟epoll的通知機(jī)制需要很多函數(shù)回調(diào)夫嗓。
2、select低效是因?yàn)槊看嗡夹枰喸兂寤唷5托б彩窍鄬?duì)的舍咖,視情況而定,也可通過良好的設(shè)計(jì)改善
14.?Linux內(nèi)存管理
主要是三個(gè)方面: 虛擬內(nèi)存管理 ? ? ? 內(nèi)核空間內(nèi)存管理 ? ? ? ? 用戶空間內(nèi)存管理
(1)Linux下锉桑,物理內(nèi)存的管理是按區(qū)劃分的排霉,一般來說32位系統(tǒng)的內(nèi)存可以分為:
ZONE_DMA? 低于16M的內(nèi)存(用于DMA訪問(直接內(nèi)存訪問))
ZONE_NORMAL 高于16M低于896M的內(nèi)存
ZONE_HIGHMEM 高于896M的內(nèi)存 (通常稱之為高端內(nèi)存)
前面已經(jīng)提到,低于896M的內(nèi)存和虛擬內(nèi)存是線性映射的民轴,內(nèi)核可以直接訪問到攻柠,而ZONE_HIGHMEM則需要調(diào)用特定的接口動(dòng)態(tài)映射使用。
在64位的系統(tǒng)下后裸,由于虛擬地址空間遠(yuǎn)遠(yuǎn)大于可安裝的物理內(nèi)存瑰钮,因此,64位下的ZONE_HIGHMEM總是空的微驶。
高端內(nèi)存的使用(Linux內(nèi)存管理-高端內(nèi)存(一) - Jessica程序猿 - 博客園)浪谴,可以通過三種機(jī)制來映射使用开睡,分別映射到 ? 內(nèi)核動(dòng)態(tài)映射空間, 永久內(nèi)核映射苟耻,臨時(shí)內(nèi)核映射
? (2)linux對(duì)物理內(nèi)存的管理主要還是體現(xiàn)在其分配和回收上篇恒。
這就要提到著名的伙伴系統(tǒng)算法了,接下來我們重點(diǎn)看下該算法為什么適用于linux下的內(nèi)存管理凶杖。
對(duì)于內(nèi)存這種頻繁申請(qǐng)釋放的資源胁艰,最大的問題應(yīng)該是如何避免內(nèi)存碎片問題。通常思路智蝠,為避免內(nèi)存碎片的情況蝗茁,可以有兩種思路:
① 在分頁時(shí),使用非連續(xù)的空閑物理頁映射到連續(xù)的線性地址空間
② 使用一種方式記錄現(xiàn)存的空閑連續(xù)頁的情況寻咒,盡量避免為滿足小塊內(nèi)存的請(qǐng)求而分割連續(xù)的大空閑塊
第一種思路在分配連續(xù)的物理內(nèi)存時(shí)可能時(shí)常會(huì)遇到困難。同時(shí)颈嚼,非連續(xù)的空閑物理頁時(shí)常映射必然導(dǎo)致頁表頻繁的被修改毛秘,這樣TLB(轉(zhuǎn)換檢測(cè)緩沖區(qū):是一個(gè)內(nèi)存管理單元,用于改進(jìn)虛擬地址到物理地址轉(zhuǎn)換速度的緩存)的命中率也會(huì)下降,對(duì)性能是有比較大的影響的阻课。
因此叫挟,linux選擇了第二種思路做為解決方案,在具體的算法上選擇了業(yè)界比較成熟的伙伴系統(tǒng)算法限煞。linux把所有的物理空閑頁分成了11個(gè)塊鏈表抹恳,每個(gè)塊鏈表分別包含了大小1,2署驻,4奋献,8,16旺上,32瓶蚂,64,128宣吱,256窃这,512和1024個(gè)連續(xù)頁框的頁框塊。最大可以申請(qǐng)1024個(gè)連續(xù)頁框征候,對(duì)應(yīng)4MB大小的連續(xù)內(nèi)存杭攻。每個(gè)頁框塊的第一個(gè)頁框的物理地址是該塊大小的整數(shù)倍。例如疤坝,大小為16個(gè)頁框的塊兆解,其起始地址是16*2^12(2^12=4096)的整數(shù)倍。
在伙伴算法的控制下卒煞,申請(qǐng)內(nèi)存和釋放內(nèi)存塊按照伙伴算法(選擇合適大小的鏈表取內(nèi)存塊痪宰,如若沒有合適大小的內(nèi)存塊,則從大小接近的鏈表中,合并或切分內(nèi)存 ? 伙伴算法原理及其簡(jiǎn)單實(shí)現(xiàn))衣撬。釋放內(nèi)存過程則是逆過程乖订,將釋放的內(nèi)存選擇合適的鏈表并加入其中。具體伙伴算法的細(xì)節(jié)具练,大家可參考相關(guān)資料乍构,這里不細(xì)表。
伙伴算法管理的內(nèi)存管理的內(nèi)存適合大塊的內(nèi)存扛点,但如果對(duì)小內(nèi)存管理哥遮,如幾個(gè)幾十幾百個(gè)字節(jié)的空間。如直接給一個(gè)頁則導(dǎo)致內(nèi)存空間的浪費(fèi)陵究。linux針對(duì)小內(nèi)存的管理眠饮,提供了另一個(gè)專門的分配器,slab分配器(【操作系統(tǒng)铜邮,進(jìn)程仪召,多線程】 - 簡(jiǎn)書 ?? 第12點(diǎn)里面)。linux的提供配置一組slab/slob/slub的選擇松蒜,不同的分配器在不同的應(yīng)用場(chǎng)景下有著不同的應(yīng)用扔茅。我們這里簡(jiǎn)單的了解一下slab分配器的基本原理,slab分配器申請(qǐng)了一系列的連續(xù)物理內(nèi)存秸苗,該內(nèi)存保存在系統(tǒng)的高速緩存當(dāng)中召娜,當(dāng)需要小內(nèi)存從這些高速緩存中直接申請(qǐng)。slab分配器并不直接釋放已分配的內(nèi)容惊楼,而是等到系統(tǒng)的內(nèi)核線程周期性的掃描高速緩存并釋放slab的內(nèi)容玖瘸。
伙伴算法:
15.? Linux寫時(shí)拷貝技術(shù)(copy-on-write)
在linux程序中,fork()會(huì)產(chǎn)生一個(gè)和父進(jìn)程完全相同的子進(jìn)程胁后,但子進(jìn)程在此后多會(huì)exec系統(tǒng)調(diào)用店读,出于效率考慮,linux中引入了“寫時(shí)復(fù)制”技術(shù)攀芯,也就是只有進(jìn)程空間的各段的內(nèi)容要發(fā)生變化時(shí)屯断,才將父進(jìn)程的內(nèi)容復(fù)制一份給子進(jìn)程。
那么子進(jìn)程的物理空間沒有代碼搔确,怎么去取指令執(zhí)行exec系統(tǒng)調(diào)用呢彼棍?灭忠?
? ? ? ? 在fork之后exec之前兩個(gè)進(jìn)程用的是相同的物理空間(內(nèi)存區(qū)),子進(jìn)程的代碼段座硕、數(shù)據(jù)段弛作、堆棧都是指向父進(jìn)程的物理空間,也就是說华匾,兩者的虛擬空間不同映琳,其對(duì)應(yīng)的物理空間是一個(gè)。當(dāng)父子進(jìn)程中有更改相應(yīng)段的行為發(fā)生時(shí)蜘拉,再為子進(jìn)程相應(yīng)的段分配物理空間萨西。如果不是因?yàn)閑xec,內(nèi)核會(huì)給子進(jìn)程的數(shù)據(jù)段旭旭、堆棧段分配相應(yīng)的物理空間(至此兩者都有各自的進(jìn)程空間谎脯,互不影響),而代碼段繼續(xù)共享父進(jìn)程的物理空間(兩者的代碼完全相同)持寄。而如果是因?yàn)閑xec穿肄,由于兩者執(zhí)行的代碼不同,子進(jìn)程的代碼段也會(huì)分配單獨(dú)的物理空間际看。
總結(jié):
? ? 傳統(tǒng)的fork()系統(tǒng)調(diào)用直接把所有的資源復(fù)制給新創(chuàng)建的進(jìn)程。這種實(shí)現(xiàn)過于簡(jiǎn)單并且效率低下矢否,因?yàn)樗截惖臄?shù)據(jù)也許并不共享仲闽,更糟的情況是,如果新進(jìn)程打算立即執(zhí)行一個(gè)新的映像僵朗,那么所有的拷貝將是無用功赖欣。
? ? Linux的fork()使用寫時(shí)拷貝(copy-on-write)頁實(shí)現(xiàn)。寫時(shí)拷貝是一種可以推遲甚至免除拷貝數(shù)據(jù)的技術(shù)验庙。內(nèi)核此時(shí)并不復(fù)制整個(gè)地址空間顶吮,而是讓父進(jìn)程和子進(jìn)程共享一個(gè)拷貝。只有在需要寫入的時(shí)候粪薛,數(shù)據(jù)才會(huì)復(fù)制悴了,從而使各個(gè)進(jìn)程擁有各自的拷貝。也就是說违寿,資源的復(fù)制只有在需要寫入的時(shí)候才進(jìn)行湃交,在此之前,只是以只讀方式共享藤巢。這種技術(shù)使地址空間的頁的拷貝被推遲到實(shí)際發(fā)生寫入的時(shí)候搞莺。
? ? 在頁根本不會(huì)被寫入的情況下,舉例來說掂咒,fork()之后立即調(diào)用exec()才沧,它們就無需復(fù)制了迈喉,fork()的實(shí)際開銷就是復(fù)制父進(jìn)程的頁表以及給子進(jìn)程創(chuàng)建唯一的進(jìn)程描述符。在一般情況下温圆,進(jìn)程創(chuàng)建后都會(huì)馬上運(yùn)行一個(gè)可執(zhí)行的文件挨摸,這種優(yōu)化可以避免拷貝大量根本不會(huì)使用的數(shù)據(jù)(地址空間常常包含數(shù)十兆的數(shù)據(jù))。由于Unix強(qiáng)調(diào)進(jìn)程快速執(zhí)行的能力捌木,所以這個(gè)優(yōu)化是很重要的油坝,注:Linux COW和exec沒有必然聯(lián)系
16. Linux內(nèi)核相關(guān)知識(shí)(內(nèi)核結(jié)構(gòu))
內(nèi)核主要是五個(gè)子系統(tǒng)組成------進(jìn)程管理,進(jìn)程間通信刨裆,內(nèi)存管理澈圈,網(wǎng)絡(luò)協(xié)議棧,虛擬文件系統(tǒng)
Linux內(nèi)核的整體架構(gòu)簡(jiǎn)介 - CSDN博客
(1)PM(Procees?Management 進(jìn)程管理)------這一部分包括具體創(chuàng)建創(chuàng)建進(jìn)程(fork疯坤、exec),停止進(jìn)程(kill报慕、exit),并控制他們之間的通信(signal等)。還包括進(jìn)程調(diào)度压怠,控制活動(dòng)進(jìn)程如何共享CPU眠冈。這一部分是Linux已經(jīng)做好的,在寫驅(qū)動(dòng)的時(shí)候菌瘫,只需要調(diào)用對(duì)應(yīng)的函數(shù)即可實(shí)現(xiàn)這些功能蜗顽,例如創(chuàng)建進(jìn)程、進(jìn)程通信等等雨让。
(2)MM(Memory?Management 內(nèi)存管理)------內(nèi)存管理的主要作用是控制多個(gè)進(jìn)程安全的共享內(nèi)存區(qū)域雇盖。
(3)IPC(Inter-Process Communication進(jìn)程間通信)------IPC不管理任何的硬件,它主要負(fù)責(zé)Linux系統(tǒng)中進(jìn)程之間的通信栖忠。
(4)Network Stack(網(wǎng)絡(luò)協(xié)議棧)------ Linux內(nèi)核中提供了豐富的網(wǎng)絡(luò)協(xié)議實(shí)現(xiàn)崔挖。
(5)VFS(Virtual?File?Systems 虛擬文件系統(tǒng))------虛擬文件系統(tǒng),隱藏各種文件系統(tǒng)的具體細(xì)節(jié)庵寞,為文件操作提供統(tǒng)一的接口虚汛。在Linux中“一切皆文件”,這些文件就是通過VFS來實(shí)現(xiàn)的皇帮。Linux提供了一個(gè)大的通用模型卷哩,使這個(gè)模型包含了所有文件系統(tǒng)功能的集合。如下圖所示属拾,是一個(gè)虛擬文件系統(tǒng)的結(jié)構(gòu)圖:
17.Linux sort 瓦堵、uniq基协、cut 命令詳解 ?
linux sort,uniq,cut,wc命令詳解 - ggjucheng - 博客園
Sort:------- sort 命令對(duì) File 參數(shù)指定的文件中的行排序,并將結(jié)果寫到標(biāo)準(zhǔn)輸出菇用。如果 File 參數(shù)指定多個(gè)文件澜驮,那么 sort 命令將這些文件連接起來,并當(dāng)作一個(gè)文件進(jìn)行排序惋鸥。(sort 是默認(rèn)以第一個(gè)數(shù)據(jù)來排序杂穷,而且默認(rèn)是以字符串形式來排序,所以由字母 a 開始升序排序)
uniq------uniq命令可以去除排序過的文件中的重復(fù)行,因此uniq經(jīng)常和sort合用卦绣。也就是說耐量,為了使uniq起作用,所有的重復(fù)行必須是相鄰的滤港。
cut------cut命令可以從一個(gè)文本文件或者文本流中提取文本列拴鸵。
18. 管道的實(shí)現(xiàn)機(jī)制
? ? ? ? 管道是由內(nèi)核管理的一個(gè)緩沖區(qū),相當(dāng)于我們放入內(nèi)存中的一個(gè)紙條蜗搔。管道的一端連接一個(gè)進(jìn)程的輸出。這個(gè)進(jìn)程會(huì)向管道中放入信息八堡。管道的另一端連接一個(gè)進(jìn)程的輸入樟凄,這個(gè)進(jìn)程取出被放入管道的信息。一個(gè)緩沖區(qū)不需要很大一般為4K大小兄渺,它被設(shè)計(jì)成為環(huán)形的數(shù)據(jù)結(jié)構(gòu)缝龄,以便管道可以被循環(huán)利用。當(dāng)管道中沒有信息的話挂谍,從管道中讀取的進(jìn)程會(huì)等待叔壤,直到另一端的進(jìn)程放入信息。當(dāng)管道被放滿信息的時(shí)候口叙,嘗試放入信息的進(jìn)程會(huì)等待炼绘,直到另一端的進(jìn)程取出信息。當(dāng)兩個(gè)進(jìn)程都終結(jié)的時(shí)候妄田,管道也自動(dòng)消失
從原理上------管道利用fork機(jī)制建立俺亮,從而讓兩個(gè)進(jìn)程可以連接到同一個(gè)PIPE上驮捍。最開始的時(shí)候,上面的兩個(gè)箭頭都連接在同一個(gè)進(jìn)程Process 1上(連接在Process 1上的兩個(gè)箭頭)脚曾。當(dāng)fork復(fù)制進(jìn)程的時(shí)候东且,會(huì)將這兩個(gè)連接也復(fù)制到新的進(jìn)程(Process 2)。隨后本讥,每個(gè)進(jìn)程關(guān)閉自己不需要的一個(gè)連接 (兩個(gè)黑色的箭頭被關(guān)閉; Process 1關(guān)閉從PIPE來的輸入連接珊泳,Process2關(guān)閉輸出到PIPE的連接),這樣拷沸,剩下的紅色連接就構(gòu)成了如上圖的PIPE色查。
實(shí)現(xiàn)細(xì)節(jié):在 Linux 中,管道的實(shí)現(xiàn)并沒有使用專門的數(shù)據(jù)結(jié)構(gòu)堵漱,而是借助了文件系統(tǒng)的file結(jié)構(gòu)和VFS的索引節(jié)點(diǎn)inode综慎。通過將兩個(gè) file 結(jié)構(gòu)指向同一個(gè)臨時(shí)的 VFS 索引節(jié)點(diǎn),而這個(gè) VFS 索引節(jié)點(diǎn)又指向一個(gè)物理頁面而實(shí)現(xiàn)的勤庐。
有兩個(gè) file 數(shù)據(jù)結(jié)構(gòu)示惊,但它們定義文件操作例程地址是不同的,其中一個(gè)是向管道中寫入數(shù)據(jù)的例程地址愉镰,而另一個(gè)是從管道中讀出數(shù)據(jù)的例程地址米罚。這樣,用戶程序的系統(tǒng)調(diào)用仍然是通常的文件操作丈探,而內(nèi)核卻利用這種抽象機(jī)制實(shí)現(xiàn)了管道這一特殊操作录择。
19. 介紹一下 makefiles ??說說Makefile那些事兒 - CSDN博客
makefile就是一個(gè)文本文件,在Makefile文件中描述了整個(gè)工程所有文件的編譯順序碗降、編譯規(guī)則隘竭,它能夠紀(jì)錄文件的信息,決定在鏈接的時(shí)候需要重新編譯哪些文件讼渊。Makefile 有自己的書寫格式动看、關(guān)鍵字、函數(shù)爪幻。而且在Makefile中可以使用系統(tǒng)shell所提供的任何命令來完成想要的工作菱皆。Makefile(在其它的系統(tǒng)上可能是另外的文件名)在絕大多數(shù)的IDE 開發(fā)環(huán)境中都在使用,已經(jīng)成為一種工程的編譯方法挨稿。
Makefile包含五個(gè)部分:顯示規(guī)則仇轻,隱式規(guī)則,變量定義奶甘,文件指示篷店,注釋
1)、顯式規(guī)則臭家。顯式規(guī)則說明了船庇,如何生成一個(gè)或多的的目標(biāo)文件吭产。這是由Makefile的書寫者明顯指出,要生成的文件鸭轮,文件的依賴文件臣淤,生成的命令。?
2)窃爷、隱式規(guī)則邑蒋。由于我們的make有自動(dòng)推導(dǎo)的功能,所以隱晦的規(guī)則可以讓我們比較粗糙地簡(jiǎn)略地書寫Makefile按厘,這是由make所支持的医吊。?
3)、變量的定義逮京。在Makefile中我們要定義一系列的變量卿堂,變量一般都是字符串,這個(gè)有點(diǎn)你C語言中的宏懒棉,當(dāng)Makefile被執(zhí)行時(shí)草描,其中的變量都會(huì)被擴(kuò)展到相應(yīng)的引用位置上。?
4)策严、文件指示穗慕。其包括了三個(gè)部分,一個(gè)是在一個(gè)Makefile中引用另一個(gè)Makefile妻导,就像C語言中的include一樣逛绵;另一個(gè)是指根據(jù)某些情況指定Makefile中的有效部分,就像C語言中的預(yù)編譯#if一樣倔韭;還有就是定義一個(gè)多行的命令术浪。有關(guān)這一部分的內(nèi)容,我會(huì)在后續(xù)的部分中講述寿酌。?
5)胰苏、注釋。Makefile中只有行注釋份名,和UNIX的Shell腳本一樣,其注釋是用“#”字符妓美,這個(gè)就像C/C++中的“//”一樣僵腺。如果你要在你的Makefile中使用“#”字符,可以用反斜框進(jìn)行轉(zhuǎn)義壶栋,如:“/#”辰如。?
最后,還值得一提的是贵试,在Makefile中的命令琉兜,必須要以[Tab]鍵開始凯正。
20.mmap介紹 ? ? 認(rèn)真分析mmap:是什么 為什么 怎么用 - 胡瀟 - 博客園
mmap是一種內(nèi)存映射文件的方法,即將一個(gè)文件或者其它對(duì)象映射到進(jìn)程的地址空間豌蟋,實(shí)現(xiàn)文件磁盤地址和進(jìn)程虛擬地址空間中一段虛擬地址的一一對(duì)映關(guān)系廊散。實(shí)現(xiàn)這樣的映射關(guān)系后,進(jìn)程就可以采用指針的方式讀寫操作這一段內(nèi)存梧疲,而系統(tǒng)會(huì)自動(dòng)回寫臟頁面到對(duì)應(yīng)的文件磁盤上允睹,即完成了對(duì)文件的操作而不必再調(diào)用read,write等系統(tǒng)調(diào)用函數(shù)。相反幌氮,內(nèi)核空間對(duì)這段區(qū)域的修改也直接反映用戶空間缭受,從而可以實(shí)現(xiàn)不同進(jìn)程間的文件共享。如下圖所示:
作用:將磁盤文件的數(shù)據(jù)映射到內(nèi)存進(jìn)程空間中该互,用戶修改內(nèi)存就能修改磁盤文件米者。
常規(guī)文件操作為了提高讀寫效率和保護(hù)磁盤闯袒,使用了頁緩存機(jī)制。這樣造成讀文件時(shí)需要先將文件頁從磁盤拷貝到頁緩存中酿愧,由于頁緩存處在內(nèi)核空間沥潭,不能被用戶進(jìn)程直接尋址,所以還需要將頁緩存中數(shù)據(jù)頁再次拷貝到內(nèi)存對(duì)應(yīng)的用戶空間中嬉挡。這樣钝鸽,通過了兩次數(shù)據(jù)拷貝過程,才能完成進(jìn)程對(duì)文件內(nèi)容的獲取任務(wù)庞钢。寫操作也是一樣拔恰,待寫入的buffer頁緩存在內(nèi)核空間不能直接訪問,必須要先拷貝至內(nèi)核空間對(duì)應(yīng)的主存基括,再寫回磁盤中(延遲寫回)颜懊,也是需要兩次數(shù)據(jù)拷貝。
而使用mmap操作文件中,創(chuàng)建新的虛擬內(nèi)存區(qū)域河爹,建立文件磁盤地址與虛擬內(nèi)存區(qū)域映射這兩步匠璧,沒有任何文件拷貝操作。而之后訪問數(shù)據(jù)時(shí)發(fā)現(xiàn)內(nèi)存中并無數(shù)據(jù)而發(fā)起的缺頁異常過程咸这,可以通過已經(jīng)建立好的映射關(guān)系夷恍,只使用一次數(shù)據(jù)拷貝,就從磁盤中將數(shù)據(jù)傳入內(nèi)存的用戶空間中炊苫,供進(jìn)程使用裁厅。
總而言之,常規(guī)文件操作需要從磁盤到頁緩存再到用戶內(nèi)存的兩次數(shù)據(jù)拷貝侨艾。而mmap操控文件执虹,只需要從磁盤到用戶內(nèi)存的一次數(shù)據(jù)拷貝過程。說白了唠梨,mmap的關(guān)鍵點(diǎn)是實(shí)現(xiàn)了用戶空間和內(nèi)核空間的數(shù)據(jù)直接交互而省去了空間不同數(shù)據(jù)不通的繁瑣過程袋励。因此mmap效率更高。
mmap的優(yōu)點(diǎn)
1)對(duì)文件的讀取操作跨過了頁緩存当叭,減少了數(shù)據(jù)的拷貝次數(shù)茬故,用內(nèi)存讀寫取代I/O讀寫,提高了文件讀取效率蚁鳖。
2)實(shí)現(xiàn)了用戶空間和內(nèi)核空間的高效交互方式磺芭。兩空間的各自修改操作可以直接反映在映射的區(qū)域內(nèi),從而被對(duì)方空間及時(shí)捕捉醉箕。
3)提供進(jìn)程間共享內(nèi)存及相互通信的方式钾腺。不管是父子進(jìn)程還是無親緣關(guān)系的進(jìn)程,都可以將自身用戶空間映射到同一個(gè)文件或匿名映射到同一片區(qū)域讥裤。從而通過各自對(duì)映射區(qū)域的改動(dòng)放棒,達(dá)到進(jìn)程間通信和進(jìn)程間共享的目的。? 同時(shí)己英,如果進(jìn)程A和進(jìn)程B都映射了區(qū)域C间螟,當(dāng)A第一次讀取C時(shí)通過缺頁從磁盤復(fù)制文件頁到內(nèi)存中;但當(dāng)B再讀C的相同頁面時(shí)损肛,雖然也會(huì)產(chǎn)生缺頁異常厢破,但是不再需要從磁盤中復(fù)制文件過來,而可直接使用已經(jīng)保存在內(nèi)存中的文件數(shù)據(jù)治拿。
4)可用于實(shí)現(xiàn)高效的大規(guī)模數(shù)據(jù)傳輸摩泪。內(nèi)存空間不足,是制約大數(shù)據(jù)操作的一個(gè)方面忍啤,解決方案往往是借助硬盤空間協(xié)助操作加勤,補(bǔ)充內(nèi)存的不足。但是進(jìn)一步會(huì)造成大量的文件I/O操作同波,極大影響效率鳄梅。這個(gè)問題可以通過mmap映射很好的解決。換句話說未檩,但凡是需要用磁盤空間代替內(nèi)存的時(shí)候戴尸,mmap都可以發(fā)揮其功效。
缺點(diǎn): 使用相對(duì)麻煩冤狡,而且讀寫操作不會(huì)阻塞孙蒙,可能會(huì)造成讀寫的快慢不同步,導(dǎo)致讀寫數(shù)據(jù)不完整悲雳。
21.Linux下的7種文件類型
22.Linux里的RCU ? ? 深入理解 Linux 的 RCU 機(jī)制 - 騰訊云+社區(qū) - 博客園
RCU(Read-Copy Update)挎峦,是 Linux 中比較重要的一種同步機(jī)制,稱為:讀拷貝更新機(jī)制合瓢,再直白點(diǎn)是“隨意讀坦胶,但更新數(shù)據(jù)的時(shí)候,需要先復(fù)制一份副本晴楔,在副本上完成修改顿苇,再一次性地替換舊數(shù)據(jù)”。這是 Linux 內(nèi)核實(shí)現(xiàn)的一種針對(duì)“讀多寫少”的共享數(shù)據(jù)的同步機(jī)制税弃。
不同于其他的同步機(jī)制纪岁,它允許多個(gè)讀者同時(shí)訪問共享數(shù)據(jù),而且讀者的性能不會(huì)受影響(“隨意讀”)则果,讀者與寫者之間也不需要同步機(jī)制(但需要“復(fù)制后再寫”)幔翰,但如果存在多個(gè)寫者時(shí),在寫者把更新后的“副本”覆蓋到原數(shù)據(jù)時(shí)短条,寫者與寫者之間需要利用其他同步機(jī)制保證同步导匣。
23 . cache緩存區(qū)和buffer緩沖區(qū)的理解
(1) Cache:緩存區(qū),是高速緩存茸时,是位于CPU和主內(nèi)存之間的容量較小但速度很快的存儲(chǔ)器贡定,因?yàn)镃PU的速度遠(yuǎn)遠(yuǎn)高于主內(nèi)存的速度,CPU從內(nèi)存中讀取數(shù)據(jù)需等待很長(zhǎng)的時(shí)間可都,而? Cache保存著CPU剛用過的數(shù)據(jù)或循環(huán)使用的部分?jǐn)?shù)據(jù)缓待,這時(shí)從Cache中讀取數(shù)據(jù)會(huì)更快,減少了CPU等待的時(shí)間渠牲,提高了系統(tǒng)的性能旋炒。
??? Cache并不是用來緩存文件的,而是用來緩存? 塊? 的( 塊是I/O讀寫最小的單元)签杈;Cache一般會(huì)用在I/O請(qǐng)求上瘫镇,如果多個(gè)進(jìn)程要訪問某個(gè)文件鼎兽,可以把此文件讀入Cache中,這樣下一個(gè)進(jìn)程獲取CPU控制權(quán)并訪問此文件直接從Cache讀取铣除,提高系統(tǒng)性能谚咬。
(2)Buffer:緩沖區(qū),用于? 存儲(chǔ)速度不同步的設(shè)備 或? 優(yōu)先級(jí)不同的設(shè)備? 之間傳輸數(shù)據(jù)尚粘;通過buffer可以減少進(jìn)程間通信需要等待的時(shí)間择卦,當(dāng)存儲(chǔ)速度快的設(shè)備與存儲(chǔ)速度慢的設(shè)備進(jìn)行通信時(shí),存儲(chǔ)慢的數(shù)據(jù)先把數(shù)據(jù)存放到buffer郎嫁,達(dá)到一定程度存儲(chǔ)快的設(shè)備再讀取buffer的數(shù)據(jù)秉继,在此期間存儲(chǔ)快的設(shè)備CPU可以干其他的事情。
Buffer一般是用在寫入磁盤的時(shí)候泽铛,例如:某個(gè)進(jìn)程要求多個(gè)字段被讀入尚辑,當(dāng)所有要求的字段被讀入之前已經(jīng)讀入的字段會(huì)先放到buffer中。
24. Linux支持的文件系統(tǒng)
Linux系統(tǒng)因?yàn)槭褂肰FS盔腔,所有其核心可以支持如ext腌巾、ext2、ext3铲觉、ext4澈蝙、JFS2等的多種的文件系統(tǒng)。下面說明其支持的幾個(gè)重要的文件系統(tǒng)撵幽。
(1)ext-----專門為linux核心做的的第一個(gè)文件系統(tǒng)灯荧。單個(gè)文件最大限制:未知;該文件系統(tǒng)最大支持2GB的容量盐杂。
(2)ext2-----由Rémy Card設(shè)計(jì)逗载,用以代替ext,是LINUX內(nèi)核所用的文件系統(tǒng)链烈。單個(gè)文件最大限制2TB厉斟;該文件系統(tǒng)最大支持32TB的容量。
(3)ext3-------一個(gè)日志文件系統(tǒng)强衡。單個(gè)文件最大限制16TB擦秽,該文件系統(tǒng)最大支持32TB的容量。
(4)ext4-------Theodore Tso領(lǐng)導(dǎo)的開發(fā)團(tuán)隊(duì)實(shí)現(xiàn),Linux系統(tǒng)下的日志文件系統(tǒng)漩勤。單個(gè)文件最大限制16TB感挥,該文件系統(tǒng)最大支持1EB的容量。
(5)JFS2---------一種字節(jié)級(jí)日志文件系統(tǒng),該文件系統(tǒng)主要是為滿足服務(wù)器的高吞吐量和可靠性需求而設(shè)計(jì)越败、開發(fā)的触幼。單個(gè)文件最大限制16TB,該文件系統(tǒng)最大支持1PB的容量究飞。
25. shell里面$置谦?堂鲤,$$,$0媒峡,$#等代表什么意思筑累?
26. wget命令 ? scp命令 ? rcp命令 ? ?wget命令 scp命令 rcp命令 - CSDN博客
(1)wget------Linux系統(tǒng)中的wget是一個(gè)下載文件的工具,它用在命令行下丝蹭。對(duì)于Linux用戶是必不可少的工具,我們經(jīng)常要下載一些軟件或從遠(yuǎn)程服務(wù)器恢復(fù)備份到本地服務(wù)器坪蚁。wget支持HTTP奔穿,HTTPS和FTP協(xié)議,可以使用HTTP代理敏晤。所謂的自動(dòng)下載是指贱田,wget可以在用戶退出系統(tǒng)的之后在后臺(tái)執(zhí)行。這意味這你可以登錄系統(tǒng)嘴脾,啟動(dòng)一個(gè)wget下載任務(wù)男摧,然后退出系統(tǒng),wget將在后臺(tái)執(zhí)行直到任務(wù)完成 译打。
wget 可以跟蹤HTML頁面上的鏈接依次下載來創(chuàng)建遠(yuǎn)程服務(wù)器的本地版本耗拓,完全重建原始站點(diǎn)的目錄結(jié)構(gòu)。這又常被稱作”遞歸下載”奏司。在遞歸下載的時(shí)候乔询,wget 遵循Robot Exclusion標(biāo)準(zhǔn)(/robots.txt). wget可以在下載的同時(shí),將鏈接轉(zhuǎn)換成指向本地文件韵洋,以方便離線瀏覽竿刁。
(2)SCP------scp是secure copy的簡(jiǎn)寫,用于在Linux下進(jìn)行遠(yuǎn)程拷貝文件的命令搪缨,和它類似的命令有cp食拜,不過cp只是在本機(jī)進(jìn)行拷貝不能跨服務(wù)器,而且scp傳輸是加密的副编「旱椋可能會(huì)稍微影響一下速度。當(dāng)你服務(wù)器硬盤變?yōu)橹蛔xread only system時(shí)痹届,用scp可以幫你把文件移出來惑惶。另外,scp還非常不占資源短纵,不會(huì)提高多少系統(tǒng)負(fù)荷带污,在這一點(diǎn)上,rsync就遠(yuǎn)遠(yuǎn)不及它了香到。雖然 rsync比scp會(huì)快一點(diǎn)鱼冀,但當(dāng)小文件眾多的情況下报破,rsync會(huì)導(dǎo)致硬盤I/O非常高,而scp基本不影響系統(tǒng)正常使用千绪。
(3)rpc------rcp代表“remote file copy”(遠(yuǎn)程文件拷貝)充易。該命令用于在計(jì)算機(jī)之間拷貝文件。rcp命令有兩種格式荸型。
第一種格式用于文件到文件的拷貝盹靴;
第二種格式用于把文件或目錄拷貝到另一個(gè)目錄中。
27.nohup(啟動(dòng)命令) ? 重定向的問題
nohup命令輸出到指定文件:
nohup ./start.sh & ? ?默認(rèn)輸出到nohup.out文件( &是讓它后臺(tái)來運(yùn)行)
nohup ./start.sh?>output? 2>&1? & ?指定輸出到output文件 ? ?? nohup重定向輸出日志