




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、,Unix/Linux 核心編程,課程內(nèi)容,Unix/Linux操作系統(tǒng)簡(jiǎn)介 GNU編譯工具GCC GNU C 內(nèi)存管理 文件I/O 進(jìn)程管理 信號(hào) 進(jìn)程間通信 多線程 網(wǎng)絡(luò)通信,Unix/Linux操作系統(tǒng),Unix操作系統(tǒng),UNIX操作系統(tǒng),是美國AT return 0; ,#include、#include_next,1.系統(tǒng)頭文件使用#include 2.用戶頭文件使用#include “” 規(guī)則: 1.系統(tǒng)頭文件會(huì)在I參數(shù)指定得目錄中查找。 2.用戶頭文件會(huì)在當(dāng)前目錄查找。 3.Unix標(biāo)準(zhǔn)系統(tǒng)目錄 /usr/local/include /usr/lib/gcc-lib/版本/inc
2、lude /usr/include 4.編譯C+優(yōu)先查找/usr/include/g+ 5.#include 會(huì)在所有標(biāo)準(zhǔn)目錄的子目錄sys中查找time.h 6.#include的文件名含擴(kuò)展,*、?無意義。除非文件名中包含*。,#line,int re=0; printf(Hello gcc使用!n); for(int i=0;i200) re+=i; printf(out:%dn,re); /代碼行數(shù)被修改 #line 200 printf(out:%dn,re,a);/人為錯(cuò)誤 printf(out:%dn,re);,#pragma,所有GCC的pragma都定義兩個(gè)詞GCC +其他
3、#pragma GCC dependency 文件名 提示符號(hào) 測(cè)試文件的時(shí)間戳,當(dāng)指定文件比當(dāng)前文件新的時(shí)候產(chǎn)生警告。 #pragma GCC poison 每次使用指定名字就會(huì)產(chǎn)生警告 pragma pack(1) ,#pragma有一個(gè)等價(jià)的宏_Pragam,#include #pragma GCC dependency ch02.c /#pragma GCC poison printf add int main() int re=0; printf(Hello gcc使用!n); int i; _Pragma(GCC poison printf add) for(i=0;i200;i+
4、) re+=i; printf(out:%dn,re); return 0; ,預(yù)定義宏介紹,編譯環(huán)境變量,C_INCLUDE_PATH: 查找頭文件的目錄。C。 CPATH:查找頭文件,相當(dāng)于-l選項(xiàng)。 CPLUS_INCLUDE_PATH :查找頭文件的目錄。C+。 LD_LIBRARY_PATH:編譯沒有影響,主要影響運(yùn)行。指定目錄便于定位共享庫。 LIBRARY_PATH:查找連接文件,相當(dāng)于-l選項(xiàng),生成匯編,編譯成匯編 gcc -S ch01.c ch01_1.c 編譯匯編 gcc ch01.s ch01_1.s -o main,創(chuàng)建靜態(tài)庫,編譯靜態(tài)庫 gcc -c -static
5、 ch01_1.c 其中-static可選,可阻止gcc使用共享庫 不使用共享庫會(huì)使可執(zhí)行文件變大,但會(huì)減少運(yùn)行時(shí)間開銷 ar指令 ar -r libmy.a ch01_1.o 語法:ar 選項(xiàng) 歸檔文件名 目標(biāo)文件列表 指令ar的常用選項(xiàng),使用靜態(tài)庫,gcc -o main ch01.c libmy.a 如果libmy.a在LIBRARY_PATH的指定目錄中,還可以采用如下方式編譯。 gcc ch01.c -o main lmy,創(chuàng)建共享庫,編譯共享庫 編譯共享庫分成兩個(gè)部分: 編譯成位置獨(dú)立代碼的目標(biāo)文件,選項(xiàng)-fpic 編譯成共享庫,選項(xiàng)-shared gcc -c -fpic ch0
6、1_1.c gcc -shared ch01_1.o -o libmy.so 使用一條指令的效果一樣 gcc -fpic -shared ch01_1.c -o libmy.so,定位共享庫,共享庫編譯的時(shí)候與靜態(tài)庫一樣依賴LIBRARAY_PATH,運(yùn)行的時(shí)候依賴LD_LIBRARY_PATH。 規(guī)則: 查找LD_LIBRARY_PATH,目錄使用冒號(hào)分隔。 /ect/ld.so.cache中找到的列表。工具ldconfig維護(hù)。 目錄/lib 目錄/usr/lib,使用共享庫,gcc ch01.c libmy.so -o main 在代碼中動(dòng)態(tài)加載共享庫: 共享庫代碼 int add(in
7、t a,int b) int c=a+b; c=c/2; return c; ,共享庫的四個(gè)函數(shù),#include void *dlopen(const char *filename, int flag); char *dlerror(void); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle); 其中dlopen的參數(shù)flag的含義如下: RTLD_LAZY:符號(hào)查找時(shí)候才加載。 RTLD_NOW:馬上加載。,其他工具簡(jiǎn)介,庫工具程序介紹,ldconfig ldconfig是一個(gè)動(dòng)態(tài)鏈接庫管理命
8、令,為了讓動(dòng)態(tài)鏈接庫為系統(tǒng)所共享,還需運(yùn)行動(dòng)態(tài)鏈接庫的管理命令-ldconfig. ldconfig 命令的用途,主要是在默認(rèn)搜尋目錄(/lib和/usr/lib)以及動(dòng)態(tài)庫配置文件/etc/ld.so.conf內(nèi)所列的目錄下,搜索出可共享的動(dòng)態(tài)鏈接庫(格式如前介紹,lib*.so*),進(jìn)而創(chuàng)建出動(dòng)態(tài)裝入程序(ld.so)所需的連接和緩存文件.緩存文件默認(rèn)為 /etc/ld.so.cache,此文件保存已排好序的動(dòng)態(tài)鏈接庫名字列表 ldconfig通常在系統(tǒng)啟動(dòng)時(shí)運(yùn)行,而當(dāng)用戶安裝了一個(gè)新的動(dòng)態(tài)鏈接庫時(shí),就需要手工運(yùn)行這個(gè)命令.,ldconfig選項(xiàng),(1) -v或-verbose : 用此選
9、項(xiàng)時(shí),ldconfig將顯示正在掃描的目錄及搜索到的動(dòng)態(tài)鏈接庫,還有它所創(chuàng)建的連接的名字. (2) -n : 用此選項(xiàng)時(shí),ldconfig僅掃描命令行指定的目錄,不掃描默認(rèn)目錄(/lib,/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄. (3) -N : 此選項(xiàng)指示ldconfig不重建緩存文件(/etc/ld.so.cache).若未用-X選項(xiàng),ldconfig照常更新文件的連接. (4) -X : 此選項(xiàng)指示ldconfig不更新文件的連接.若未用-N選項(xiàng),則緩存文件正常更新. (5) -f CONF : 此選項(xiàng)指定動(dòng)態(tài)鏈接庫的配置文件為CONF,系統(tǒng)默認(rèn)為/
10、etc/ld.so.conf. (6) -C CACHE : 此選項(xiàng)指定生成的緩存文件為CACHE,系統(tǒng)默認(rèn)的是/etc/ld.so.cache,此文件存放已排好序的可共享的動(dòng)態(tài)鏈接庫的列表.,(7) -r ROOT : 此選項(xiàng)改變應(yīng)用程序的根目錄為ROOT(是調(diào)用chroot函數(shù)實(shí)現(xiàn)的).選擇此項(xiàng)時(shí),系統(tǒng)默認(rèn)的配置文件/etc/ld.so.conf,實(shí)際對(duì)應(yīng)的為 ROOT/etc/ld.so.conf.如用-r /usr/zzz時(shí),打開配置文件/etc/ld.so.conf時(shí),實(shí)際打開的是/usr/zzz/etc/ld.so.conf文件.用此選項(xiàng),可以大大增加動(dòng)態(tài)鏈接庫管理的靈活性. (8
11、) -l : 通常情況下,ldconfig搜索動(dòng)態(tài)鏈接庫時(shí)將自動(dòng)建立動(dòng)態(tài)鏈接庫的連接.選擇此項(xiàng)時(shí),將進(jìn)入專家模式,需要手工設(shè)置連接.一般用戶不用此項(xiàng). (9) -p或-print-cache : 此選項(xiàng)指示ldconfig打印出當(dāng)前緩存文件所保存的所有共享庫的名字. (10) -c FORMAT 或 -format=FORMAT : 此選項(xiàng)用于指定緩存文件所使用的格式,共有三種:old(老格式),new(新格式)和compat(兼容格式,此為默認(rèn)格式). (11) -V : 此選項(xiàng)打印出ldconfig的版本信息,而后退出.(12) -? 或 -help 或 -usage : 這三個(gè)選項(xiàng)作用相
12、同,都是讓ldconfig打印出其幫助信息,而后退出.,nm,nm 用來列出目標(biāo)文件的符號(hào)清單 常用參數(shù):,strip,去除指定目標(biāo)文件與靜態(tài)庫中的調(diào)試信息 :strip ch01_1.o libmy.a,ldd,列出共享庫的依賴關(guān)系:ldd libmy.so,objdump,顯示二進(jìn)制文件信息 以一種可閱讀的格式讓你更多地了解二進(jìn)制文件可能帶有的附加信息 -source -S 盡可能反匯編出源代碼,尤其當(dāng)編譯的時(shí)候指定了-g這種調(diào)試參數(shù)時(shí), 效果比較明顯。隱含了-d參數(shù)。 -show-raw-insn 反匯編的時(shí)候,顯示每條匯編指令對(duì)應(yīng)的機(jī)器碼,除非指定了 -prefix-addresses
13、,這將是缺省選項(xiàng)。 -no-show-raw-insn 反匯編時(shí),不顯示匯編指令的機(jī)器碼,這是指定 -prefix-addresses 選項(xiàng)時(shí)的缺省設(shè)置。,錯(cuò)誤處理,異常處理方式,根據(jù)函數(shù)返回值判斷異常 返回一般用戶數(shù)據(jù) -1:表示異常,其他就是用戶數(shù)據(jù) 返回指針用戶數(shù)據(jù) NULL指針,OXFFFFFFFF指針表示錯(cuò)誤 其他就是指針用戶數(shù)據(jù) 返回值不是用戶數(shù)據(jù),只是用來指明函數(shù)調(diào)用狀態(tài)。 0:成功 -1:失敗 返回void。一般不會(huì)發(fā)生錯(cuò)誤,異常處理方式,使用外部全局變量errno獲取異常原因 根據(jù)errno得到異常編號(hào) errno在函數(shù)調(diào)用正確不會(huì)被修改 絕對(duì)不要通過errno判定錯(cuò)誤 把e
14、rrno轉(zhuǎn)換為字符串 strerror函數(shù) perror函數(shù) printf函數(shù) printf()的格式輸出%m格式,環(huán)境變量,環(huán)境表 每個(gè)程序都會(huì)接收到一張環(huán)境表,是一個(gè)字符指針數(shù)組。數(shù)組以null做為結(jié)束。 全局變量environ保存了該數(shù)組的首地址。 環(huán)境變量操作函數(shù),內(nèi)存管理在語言結(jié)構(gòu)上的變化,從malloc/free到new/delete C+是強(qiáng)類型語言,new/delete的主要成果也就是加強(qiáng)了類型觀念,減少了強(qiáng)制類型轉(zhuǎn)換的需求。但是從內(nèi)存管理角度看,這個(gè)變革并沒有多少的突破性 從new/delete到內(nèi)存配置器(allocator) allocator的引入也是C+內(nèi)存管理一個(gè)突
15、破。留意一下你就可以發(fā)現(xiàn),整個(gè)STL所有組件的內(nèi)存均從allocator分配。也就是說,STL并不推薦使用new/delete進(jìn)行內(nèi)存管理,而是推薦使用allocator.,Unix/Linux內(nèi)存管理,Unix/Linux低層采用三層結(jié)構(gòu),實(shí)際使用中可以方便映射到兩層或者三層結(jié)構(gòu),以適用不同的硬件結(jié)構(gòu)。最下層的申請(qǐng)內(nèi)存函數(shù)get_free_page。之上有三種類型的內(nèi)存分配函數(shù) 1.kmalloc類型。內(nèi)核進(jìn)程使用,基于切片(slab)技術(shù),用于管理小于內(nèi)存頁的內(nèi)存申請(qǐng)。思想出發(fā)點(diǎn)和應(yīng)用層面的內(nèi)存緩沖池同出一轍。但它針對(duì)內(nèi)核結(jié)構(gòu),特別處理,應(yīng)用場(chǎng)景固定,不考慮釋放。 2.vmalloc類型。
16、內(nèi)核進(jìn)程使用。用于申請(qǐng)不連續(xù)內(nèi)存。 3.brk/mmap類型。用戶進(jìn)程使用。malloc/free實(shí)現(xiàn)的基礎(chǔ)。,進(jìn)程與內(nèi)存,所有進(jìn)程(執(zhí)行的程序)都必須占用一定數(shù)量的內(nèi)存 對(duì)任何一個(gè)普通進(jìn)程來講,它都會(huì)涉及到5種不同的數(shù)據(jù)段 代碼段:代碼段是用來存放可執(zhí)行文件的操作指令,也就是說是它是可執(zhí)行程序在內(nèi)存種的鏡像。代碼段需要防止在運(yùn)行時(shí)被非法修改,所以只準(zhǔn)許讀取操作,而不允許寫入(修改)操作它是不可寫的。 數(shù)據(jù)段:數(shù)據(jù)段用來存放可執(zhí)行文件中已初始化全局變量,換句話說就是存放程序靜態(tài)分配的變量和全局變量。 BSS段:BSS段包含了程序中未初始化全局變量,在內(nèi)存中 bss段全部置零。 Block st
17、arted by symbol,堆和棧,堆(heap):堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減) 棧:棧是用戶存放程序臨時(shí)創(chuàng)建的局部變量,也就是說我們函數(shù)括弧“”中定義的變量(但不包括static聲明的變量,static意味這在數(shù)據(jù)段中存放變量)。除此以外在函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也回被存放回棧中。由于棧的后進(jìn)先出特點(diǎn),所以棧特別方便用來保存/恢復(fù)調(diào)用
18、現(xiàn)場(chǎng)。從這個(gè)意義上將我們可以把堆??闯梢粋€(gè)臨時(shí)數(shù)據(jù)寄存、交換的內(nèi)存區(qū)。,進(jìn)程如何組織這些區(qū)域,上述幾種內(nèi)存區(qū)域中數(shù)據(jù)段、BSS和堆通常是被連續(xù)存儲(chǔ)的內(nèi)存位置上是連續(xù)的,而代碼段和棧往往會(huì)被獨(dú)立存放。有趣的是堆和棧兩個(gè)區(qū)域關(guān)系很“曖昧”,他們一個(gè)向下“長”(i386體系結(jié)構(gòu)中棧向下、堆向上),一個(gè)向上“長”,相對(duì)而生。但你不必?fù)?dān)心他們會(huì)碰頭,因?yàn)樗麄冎g間隔很大,查看內(nèi)存結(jié)構(gòu),/proc/進(jìn)程ID目錄 cat maps size 文件名 報(bào)告正文段、數(shù)據(jù)段和bss段的長度,虛擬內(nèi)存管理技術(shù),Linux操作系統(tǒng)采用虛擬內(nèi)存管理技術(shù),使得每個(gè)進(jìn)程都有各自互不干涉的進(jìn)程地址空間。該空間是塊大小為4G的
19、線性虛擬空間,用戶所看到和接觸的都是該虛擬地址,無法看到實(shí)際的物理內(nèi)存地址。利用這種虛擬地址不但能起到保護(hù)操作系統(tǒng)的效果(用戶不能直接訪問物理內(nèi)存),而且更重要的是用戶程序可使用比實(shí)際物理內(nèi)存更大的地址空間 4G的進(jìn)程地址空間被人為的分為兩個(gè)部分用戶空間與內(nèi)核空間。用戶空間從0到3G(0 xC0000000),內(nèi)核空間占據(jù)3G到4G。用戶進(jìn)程通常情況下只能訪問用戶空間的虛擬地址,不能訪問內(nèi)核空間虛擬地址。例外情況只有用戶進(jìn)程進(jìn)行系統(tǒng)調(diào)用(代表用戶進(jìn)程在內(nèi)核態(tài)執(zhí)行)等時(shí)刻可以訪問到內(nèi)核空間。,虛擬內(nèi)存管理技術(shù),用戶空間對(duì)應(yīng)進(jìn)程,所以每當(dāng)進(jìn)程切換,用戶空間就會(huì)跟著變化;而內(nèi)核空間是由內(nèi)核負(fù)責(zé)映射,
20、它并不會(huì)跟著進(jìn)程改變,是固定的。內(nèi)核空間地址有自己對(duì)應(yīng)的頁表(init_mm.pgd),用戶進(jìn)程各自有不同的頁表 每個(gè)進(jìn)程的用戶空間都是完全獨(dú)立、互不相干的。你可以把程序同時(shí)運(yùn)行10次(當(dāng)然為了同時(shí)運(yùn)行,讓它們?cè)诜祷厍耙煌?00秒吧),你會(huì)看到10個(gè)進(jìn)程占用的線性地址一模一樣。,進(jìn)程內(nèi)存管理,進(jìn)程內(nèi)存管理的對(duì)象是進(jìn)程線性地址空間上的內(nèi)存鏡像,這些內(nèi)存鏡像其實(shí)就是進(jìn)程使用的虛擬內(nèi)存區(qū)域(memory region)。進(jìn)程虛擬空間是個(gè)32或64位的“平坦”(獨(dú)立的連續(xù)區(qū)間)地址空間(空間的具體大小取決于體系結(jié)構(gòu))。要統(tǒng)一管理這么大的平坦空間可絕非易事,為了方便管理,虛擬空間被化分為許多大小可變
21、的(但必須是4096的倍數(shù))內(nèi)存區(qū)域,這些區(qū)域在進(jìn)程線性地址中像停車位一樣有序排列。這些區(qū)域的劃分原則是“將訪問屬性一致的地址空間存放在一起”,所謂訪問屬性在這里無非指的是“可讀、可寫、可執(zhí)行等”。,物理內(nèi)存管理(頁管理),Linux內(nèi)核管理物理內(nèi)存是通過分頁機(jī)制實(shí)現(xiàn)的,它將整個(gè)內(nèi)存劃分成無數(shù)4k(在i386體系結(jié)構(gòu)中)大小頁,從而分配和回收內(nèi)存的基本單位便是內(nèi)存頁了。利用分頁管理有助于靈活分配內(nèi)存地址,因?yàn)榉峙鋾r(shí)不必要求必須有大塊的連續(xù)內(nèi)存,系統(tǒng)可以東一頁、西一頁的湊出所需要的內(nèi)存供進(jìn)程使用。雖然如此,但是實(shí)際上系統(tǒng)使用內(nèi)存還是傾向于分配連續(xù)的內(nèi)存塊,因?yàn)榉峙溥B續(xù)內(nèi)存時(shí),頁表不需要更改,因此
22、能降低刷新率(頻繁刷新會(huì)很大增加訪問速度)。 getpagesize();,brk/sbrk的虛擬內(nèi)存管理,void *sbrk(int size) Size=0返回sbrk/brk上次的末尾地址 size0 分配內(nèi)存空間,返回上一次末尾地址 size0 釋放空間 int brk(void* ptr) 直接修改訪問的有效范圍的末尾地址 釋放空間形成一個(gè)完整的page,則該頁影射被解除 返回: 0:分配成功 -1:失敗,系統(tǒng)底層的內(nèi)存映射(mmap/munmap),#include void *mmap(void *start, size_t length, int prot, int flag
23、s, int fd, off_t offset); int munmap(void *start, size_t length); 參數(shù)start:指向欲映射的內(nèi)存起始地址,通常設(shè)為 NULL,代表讓系統(tǒng)自動(dòng)選定地址,映射成功后返回該地址。 參數(shù)length:代表將文件中多大的部分映射到內(nèi)存。 映射空間大小。建議4k倍數(shù),不是4K倍數(shù),自動(dòng)對(duì)齊 參數(shù)prot: 映射區(qū)域的保護(hù)方式??梢詾橐韵聨追N方式的組合: 1.PROT_EXEC 映射區(qū)域可被執(zhí)行 2.PROT_READ 映射區(qū)域可被讀取 3.PROT_WRITE 映射區(qū)域可被寫入 4.PROT_NONE 映射區(qū)域不能存取,mmap,參數(shù)fl
24、ags:影響映射區(qū)域的各種特性。在調(diào)用mmap()時(shí)必須要指定MAP_SHARED 或MAP_PRIVATE。 1.MAP_FIXED 如果參數(shù)start所指的地址無法成功建立映射時(shí),則放棄映射,不對(duì)地址做修正。通常不鼓勵(lì)用此標(biāo)志。 2.MAP_SHARED對(duì)映射區(qū)域的寫入數(shù)據(jù)會(huì)復(fù)制回文件內(nèi),而且允許其他映射該文件的進(jìn)程共享。 3.MAP_PRIVATE 對(duì)映射區(qū)域的寫入操作會(huì)產(chǎn)生一個(gè)映射文件的復(fù)制,即私人的“寫入時(shí)復(fù)制”(copy on write)對(duì)此區(qū)域作的任何修改都不會(huì)寫回原來的文件內(nèi)容。 4.MAP_ANONYMOUS建立匿名映射。此時(shí)會(huì)忽略參數(shù)fd,不涉及文件,而且映射區(qū)域無法和其
25、他進(jìn)程共享。 5.MAP_DENYWRITE只允許對(duì)映射區(qū)域的寫入操作,其他對(duì)文件直接寫入的操作將會(huì)被拒絕。 6.MAP_LOCKED 將映射區(qū)域鎖定住,這表示該區(qū)域不會(huì)被置換(swap)。,mmap,參數(shù)fd 要映射到內(nèi)存中的文件描述符。如果使用匿名內(nèi)存映射時(shí),即flags中設(shè)置了MAP_ANONYMOUS,fd設(shè)為-1。有些系統(tǒng)不支持匿名內(nèi)存映射,則可以使用fopen打開/dev/zero文件,然后對(duì)該文件進(jìn)行映射,可以同樣達(dá)到匿名內(nèi)存映射的效果。 參數(shù)offset: 文件映射的偏移量,通常設(shè)置為0,代表從文件最前方開始對(duì)應(yīng),offset必須是分頁大小的整數(shù)倍。 返回值:若映射成功則返回映
26、射區(qū)的內(nèi)存起始地址,否則返回MAP_FAILED(1),錯(cuò)誤原因存于errno 中。,errno,錯(cuò)誤代碼: 1.EBADF 參數(shù)fd 不是有效的文件描述詞 2.EACCES 存取權(quán)限有誤。如果是MAP_PRIVATE 情況下文件必須可讀,使用MAP_SHARED則要有PROT_WRITE以及該文件要能寫入。 3.EINVAL 參數(shù)start、length 或offset有一個(gè)不合法。 4.EAGAIN 文件被鎖住,或是有太多內(nèi)存被鎖住。 5.ENOMEM 內(nèi)存不足。,系統(tǒng)調(diào)用,系統(tǒng)調(diào)用,Linux 大部分的系統(tǒng)功能是通過系統(tǒng)調(diào)用(System Call)來實(shí)現(xiàn)的.如open,send之類.
27、這些函數(shù)在C程序調(diào)用起來跟標(biāo)準(zhǔn)C庫函數(shù)(printf)非常類似.但是實(shí)現(xiàn)機(jī)制完全不同. 庫函數(shù)仍然是運(yùn)行在Linux 用戶空間程序.很多時(shí)候內(nèi)部會(huì)調(diào)用系統(tǒng)調(diào)用. 但系統(tǒng)調(diào)用是內(nèi)核實(shí)現(xiàn)的.在C庫封裝成函數(shù).但通過系統(tǒng)軟中斷進(jìn)行調(diào)用. 用time命令測(cè)試時(shí)間,系統(tǒng)時(shí)間實(shí)際就是系統(tǒng)調(diào)用時(shí)間累積 time ./demo1 用strace 可以跟蹤一種程序系統(tǒng)調(diào)用使用情況 strace ./demo1 #不需要調(diào)試信息,庫函數(shù)與系統(tǒng)調(diào)用的關(guān)系,以是C庫函數(shù)malloc與系統(tǒng)調(diào)用sbrk的關(guān)系,文件控制,Linux文件結(jié)構(gòu),Linux環(huán)境中的文件具有特別重要的意義,因?yàn)樗鼈優(yōu)椴僮飨到y(tǒng)服務(wù)和設(shè)備提供了一個(gè)簡(jiǎn)
28、單而統(tǒng)一的接口.在Linux中,一切(或幾乎一切)都是文件。 通常程序完全可以像使用文件那樣使用磁盤文件、串行口、打印機(jī)和其他設(shè)備。 大多數(shù)情況下,你只需要使用五個(gè)基本的函數(shù)open、close、read、write和ioctl Linux中的任何事物都可以用一個(gè)文件代表,或者可以通過特殊的文件進(jìn)行操作。,Linux文件結(jié)構(gòu)(2),一些特殊文件 目錄 設(shè)備文件 /dev/console /dev/tty /dev/null,底層庫函數(shù),Linux 在底層實(shí)現(xiàn)一整套處理文件函數(shù). 這一些函數(shù)能處理普通文件,網(wǎng)絡(luò)socket文件,設(shè)備文件等 全部是系統(tǒng)調(diào)用實(shí)現(xiàn)的函數(shù) 文件處理函數(shù) open 打開或
29、創(chuàng)建一個(gè)文件 creat 建立一個(gè)空文件 close 關(guān)閉一個(gè)文件 read 從文件讀入數(shù)據(jù) write 向文件寫入一個(gè)數(shù)據(jù) lseek 在文件中移動(dòng)讀寫位置 unlink 刪除一個(gè)文件 remove 刪除一個(gè)文件本身 fcntl 控制一個(gè)文件屬性,文件描述符,值為一個(gè)非負(fù)整數(shù) 用于表示一個(gè)打開文件 在內(nèi)核空間被引用,并且由系統(tǒng)調(diào)用(open)所創(chuàng)建 read,write使用文件描述符 內(nèi)核缺省打開三個(gè)文件描述符 1-標(biāo)準(zhǔn)輸出 2-錯(cuò)誤輸出 0-標(biāo)準(zhǔn)輸入 unistd.h中,0,1,2應(yīng)當(dāng)替換成STDIN_FILENO,STDOUT_FILENO,STDERR_FILENO. 文件描述符的變化
30、范圍是0OPEN_MAX。OPEN_MAX有可能是63,linux允許更大的值。,Open函數(shù),#include int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); 第三個(gè)參數(shù)(.)僅當(dāng)創(chuàng)建新文件時(shí)才使用,用于指定文件的訪問權(quán)限位(access permission bits) flags 用于指定文件的打開/創(chuàng)建模式,這個(gè)參數(shù)可由以下常量(定義于 fcntl
31、.h)通過邏輯或構(gòu)成。 1.O_RDONLY 只讀模式 2.O_WRONLY 只寫模式 3.O_RDWR 讀寫模式 打開/創(chuàng)建文件時(shí),至少得使用上述三個(gè)常量中的一個(gè),Open函數(shù),以下常量是選用的: 1.O_APPEND 每次寫操作都寫入文件的末尾 2.O_CREAT 如果指定文件不存在,則創(chuàng)建這個(gè)文件 3.O_EXCL 如果要?jiǎng)?chuàng)建的文件已存在,則返回 -1,并且修改 errno 的值 4.O_TRUNC 如果文件存在,并且以只寫/讀寫方式打開,則清空文件全部內(nèi)容 5.O_NOCTTY 如果路徑名指向終端設(shè)備,不要把這個(gè)設(shè)備用作控制終端。 6.O_NONBLOCK 如果路徑名指向 FIFO/塊
32、文件/字符文件,則把文件的打開和后繼 I/O設(shè)置為非阻塞模式(nonblocking mode),open函數(shù),以下三個(gè)常量同樣是選用的,它們用于同步輸入輸出 1.O_DSYNC 等待物理 I/O 結(jié)束后再 write。在不影響讀取新寫入的數(shù)據(jù)的前提下,不等待文件屬性更新。 2.O_RSYNC read 等待所有寫入同一區(qū)域的寫操作完成后再進(jìn)行 3.O_SYNC 等待物理 I/O 結(jié)束后再 write,包括更新文件屬性的 I/O open 返回的文件描述符一定是最小的未被使用的描述符 一個(gè)進(jìn)程同時(shí)打開文件的個(gè)數(shù)是有限的,這個(gè)限制通常由limits.h頭文件中的常量OPEN_MAX決定 POSI
33、X要求最少16 通常被設(shè)置成256,函數(shù)說明:write,#include ssize_t write(int filedes, const void *buf, size_t nbytes); 返回值:寫入文件的字節(jié)數(shù)(成功);-1(出錯(cuò)) write 函數(shù)向 filedes 中寫入 nbytes 字節(jié)數(shù)據(jù),數(shù)據(jù)來源為 buf 。返回值一般總是等于 nbytes,否則就是出錯(cuò)了。常見的出錯(cuò)原因是磁盤空間滿了或者超過了文件大小限制。,函數(shù)說明:read,#include ssize_t read(int filedes, void *buf, size_t nbytes); 返回值:讀取到的字
34、節(jié)數(shù);0(讀到 EOF);-1(出錯(cuò)) read 函數(shù)從 filedes 指定的已打開文件中讀取 nbytes 字節(jié)到 buf 中。以下幾種情況會(huì)導(dǎo)致讀取到的字節(jié)數(shù)小于 nbytes : A. 讀取普通文件時(shí),讀到文件末尾還不夠 nbytes 字節(jié)。例如:如果文件只有 30 字節(jié),而我們想讀取 100 字節(jié),那么實(shí)際讀到的只有 30 字節(jié),read 函數(shù)返回 30 。此時(shí)再使用 read 函數(shù)作用于這個(gè)文件會(huì)導(dǎo)致 read 返回 0 。 B. 從終端設(shè)備(terminal device)讀取時(shí),一般情況下每次只能讀取一行。,函數(shù)說明:read,C. 從網(wǎng)絡(luò)讀取時(shí),網(wǎng)絡(luò)緩存可能導(dǎo)致讀取的字節(jié)數(shù)小
35、于 nbytes 字節(jié)。 D. 讀取 pipe 或者 FIFO 時(shí),pipe 或 FIFO 里的字節(jié)數(shù)可能小于 nbytes 。 E. 從面向記錄(record-oriented)的設(shè)備讀取時(shí),某些面向記錄的設(shè)備(如磁帶)每次最多只能返回一個(gè)記錄。 F. 在讀取了部分?jǐn)?shù)據(jù)時(shí)被信號(hào)中斷。,函數(shù)說明: close,close調(diào)用終止一個(gè)文件描述符fildes與其對(duì)應(yīng)文件之間的關(guān)聯(lián)。文件描述符被釋放并能夠重新使用。close調(diào)用成功就返回0,出錯(cuò)就返回-1。 有時(shí)檢查close調(diào)用的返回結(jié)果十分重要。有的文件系統(tǒng),特別是網(wǎng)絡(luò)文件系統(tǒng),可能不會(huì)在關(guān)閉文件之前報(bào)告文件寫操作中出現(xiàn)的錯(cuò)誤,因?yàn)閳?zhí)行寫操作時(shí)
36、,數(shù)據(jù)可能未被確認(rèn)寫入。 關(guān)閉一個(gè)文件時(shí)會(huì)釋放該進(jìn)程加在文件上的所有記錄鎖 當(dāng)一個(gè)進(jìn)程終止,內(nèi)核自動(dòng)關(guān)閉它所有打開的文件。,lseek函數(shù),每個(gè)打開的文件都有一個(gè)與其相關(guān)的“當(dāng)前文件偏移量” 偏移量通常是一個(gè)非負(fù)整數(shù),用以度量從文件開始處計(jì)算的字節(jié)數(shù)。 讀、寫操作都從當(dāng)前文件偏移量處開始,并使偏移量增加所讀寫的字節(jié)數(shù)。 當(dāng)打開一個(gè)文件時(shí),除非指定O_CREAT,否則偏移量被設(shè)置為0 該函數(shù)僅將當(dāng)前的文件偏移量記錄在內(nèi)核中,它并不會(huì)引起任何I/O操作。 文件偏移量可以大于文件的當(dāng)前長度。對(duì)該文件的下一次讀寫會(huì)加長該文件,并形成文件空洞,這個(gè)是允許的 文件空洞并不要求在磁盤上占用存儲(chǔ)區(qū),但對(duì)于新寫
37、的數(shù)據(jù)需要分配磁盤塊,打開文件的內(nèi)核數(shù)據(jù)結(jié)構(gòu),dup,dup2函數(shù),復(fù)制一個(gè)現(xiàn)在的文件描述符 Dup返回的返回的一定是當(dāng)前可用描述符的最小值 dup2可由第二個(gè)參數(shù)指定描述符值,如果指定的文件已經(jīng)打開,那么先關(guān)閉文件 一定程度上和fcntl功能相同,sync,fsync,fdatasync,大多數(shù)磁盤IO都通過緩沖進(jìn)行,寫入文件時(shí)先寫入緩沖區(qū),如果緩沖未滿,則不將其排入輸出隊(duì)列,這種方式叫做延遲寫。 延遲寫減少了磁盤寫次數(shù),但降低了文件內(nèi)容更新速度 這三個(gè)函數(shù)可以保證緩沖區(qū)和實(shí)際文件系統(tǒng)的數(shù)據(jù)一致。 sync將所有修改過的緩沖區(qū)排入寫隊(duì)列,然后就返回,并不等實(shí)際寫磁盤 fsync只對(duì)一個(gè)文件,
38、并且等實(shí)際寫磁盤完成才返回 fdatasync只更新數(shù)據(jù),不更新文件屬性,fcntl函數(shù),#include int fcntl(int fd , int cmd); int fcntl(int fd,int cmd,long arg); int fcntl(int fd,int cmd,struct flock * lock); 函數(shù)說明: fcntl()用來操作文件描述詞的一些特性。 參數(shù)fd代表欲設(shè)置的文件描述詞. 參數(shù)cmd代表欲操作的指令。,fcntl函數(shù),cmd有以下幾種情況: F_DUPFD用來查找大于或等于參數(shù)arg的最小且仍未使用的文件描述符,并且復(fù)制參數(shù)fd的文件描述符。執(zhí)行
39、成功則返回新復(fù)制的文件描述符。請(qǐng)參考 dup2()。 F_SETFD 設(shè)置新的文件標(biāo)志,新標(biāo)志按第三個(gè)參數(shù)設(shè)置 通常僅用來設(shè)置FD_CLOEXEC FD_CLOEXEC的作用是決定是否在成功調(diào)用了某個(gè)exec系列的系統(tǒng)調(diào)用之后關(guān)閉該文件描述符 F_GETFL 取得文件描述符狀態(tài)標(biāo)志,此標(biāo)志為open()的參數(shù)flags。 F_SETFL 設(shè)置文件描述詞狀態(tài)標(biāo)志 ,參數(shù)arg為新標(biāo)志 ,但只允許O_APPEND、O_NONBLOCK和O_ASYNC位的改變,其他位的改變將不受影響。,fcntl函數(shù),F_GETLK 取得文件鎖定的狀態(tài)。 F_SETLK 設(shè)置文件鎖定的狀態(tài)。此時(shí)flcok 結(jié)構(gòu)的l
40、_type 值必須是F_RDLCK、F_WRLCK或F_UNLCK。如果無法建立鎖定,則返回-1,錯(cuò)誤代碼為EACCES 或EAGAIN。 F_SETLKW F_SETLK 作用相同,但是無法建立鎖定時(shí),此調(diào)用會(huì)一直等到鎖定動(dòng)作成功為止。若在等待鎖定的過程中被信號(hào)中斷時(shí),會(huì)立即返回-1,錯(cuò)誤代碼為EINTR。參數(shù)lock指針為flock 結(jié)構(gòu)指針,定義如下 struct flcok short int l_type; /* 鎖定的狀態(tài)*/ short int l_whence;/*決定l_start位置*/ off_t l_start; /*鎖定區(qū)域的開頭位置*/ off_t l_len; /
41、*鎖定區(qū)域的大小*/ pid_t l_pid; /*鎖定動(dòng)作的進(jìn)程*/ ;,fcntl函數(shù),l_type 有三種狀態(tài): F_RDLCK 建立一個(gè)供讀取用的鎖定 F_WRLCK 建立一個(gè)供寫入用的鎖定 F_UNLCK 刪除之前建立的鎖定 l_whence 也有三種方式: SEEK_SET 以文件開頭為鎖定的起始位置。 SEEK_CUR 以目前文件讀寫位置為鎖定的起始位置 SEEK_END 以文件結(jié)尾為鎖定的起始位置。,stat,fstat, lstat,int stat(const char *path, struct stat *buf); 提供文件名字,獲取文件對(duì)應(yīng)屬性 int fstat(
42、int filedes, struct stat *buf); 通過文件描述符獲取文件對(duì)應(yīng)的屬性。 int lstat(const char *path, struct stat *buf); 連接文件描述符,獲取文件屬性,struct stat,struct stat mode_t st_mode; /文件對(duì)應(yīng)的模式,文件,目錄等 ino_t st_ino; /inode節(jié)點(diǎn)號(hào) dev_t st_dev; /設(shè)備號(hào)碼 dev_t st_rdev; /特殊設(shè)備號(hào)碼 nlink_t st_nlink; /文件的連接數(shù) uid_t st_uid; /文件所有者 gid_t st_gid; /文件所
43、有者對(duì)應(yīng)的組 off_t st_size; /普通文件,對(duì)應(yīng)的文件字節(jié)數(shù) time_t st_atime; /文件最后被訪問的時(shí)間 time_t st_mtime; /文件內(nèi)容最后被修改的時(shí)間 time_t st_ctime; /文件狀態(tài)改變時(shí)間 blksize_t st_blksize; /文件內(nèi)容對(duì)應(yīng)的塊大小 blkcnt_t st_blocks; /文件內(nèi)容對(duì)應(yīng)的塊數(shù)量 ;,st_mode,S_IFSOCK 0140000 scoket S_IFLNK 0120000 符號(hào)連接 S_IFREG 0100000 一般文件 S_IFBLK 0060000 區(qū)塊裝置 S_IFDIR 00400
44、00 目錄 S_IFCHR 0020000 字符裝置 S_IFIFO 0010000 先進(jìn)先出 S_ISUID 04000 文件的(set user-id on execution)位 S_ISGID 02000 文件的(set group-id on execution)位 S_ISVTX 01000 文件的sticky位 S_IRUSR(S_IREAD) 00400 文件所有者具可讀取權(quán)限 S_IWUSR(S_IWRITE)00200 文件所有者具可寫入權(quán)限 S_IXUSR(S_IEXEC) 00100 文件所有者具可執(zhí)行權(quán)限 S_IRGRP 00040 用戶組具可讀取權(quán)限 S_IWGRP
45、 00020 用戶組具可寫入權(quán)限 S_IXGRP 00010 用戶組具可執(zhí)行權(quán)限 S_IROTH 00004 其他用戶具可讀取權(quán)限 S_IWOTH 00002 其他用戶具可寫入權(quán)限 S_IXOTH 00001 其他用戶具可執(zhí)行權(quán)限,sys/stat.h中的文件類型宏函數(shù),返回值: 執(zhí)行成功則返回0,失敗返回-1,錯(cuò)誤代碼存于errno 錯(cuò)誤代碼: ENOENT 參數(shù)file_name指定的文件不存在 ENOTDIR 路徑中的目錄存在但卻非真正的目錄 ELOOP 欲打開的文件有過多符號(hào)連接問題,上限為16符號(hào)連接 EFAULT 參數(shù)buf為無效指針,指向無法存在的內(nèi)存空間 EACCESS 存取文
46、件時(shí)被拒絕 ENOMEM 核心內(nèi)存不足 ENAMETOOLONG 參數(shù)file_name的路徑名稱太長,文件訪問權(quán)限,st_mode值也包含了文件訪問權(quán)限,屏蔽位如下表,access函數(shù),按實(shí)際用戶ID和實(shí)際組ID進(jìn)行訪問權(quán)限測(cè)試。 測(cè)試成功返回0,出錯(cuò)返回-1 測(cè)試中的mode 常量,umask,為進(jìn)程設(shè)置文件模式創(chuàng)建屏蔽字,并返回以前的值 參數(shù)是由9個(gè)常量(S_IRUSR,S_IWUSR等)中的若干位按位或構(gòu)成的,chmod、fchmod,更改文件訪問權(quán)限,Chmod是在指定文件上操作,fchmod是在打開的文件上操作 Chmod函數(shù)的mode常量,來自sys/stat.h,chown、f
47、chown、lchown,更改文件的用戶id和組id 如果任意id參數(shù)為-1,則保持不變 只有超級(jí)用戶進(jìn)程改變文件的用戶id 如果進(jìn)程擁有些文件,非超級(jí)用戶也可以修改,truncate、ftruncate,文件截短成指定長度,link、unlink、remove和rename,link,創(chuàng)建一個(gè)指向現(xiàn)在文件的鏈接 unlink,刪除一個(gè)文件的鏈接 只有當(dāng)鏈接數(shù)達(dá)到0時(shí),文件刪除。另外,當(dāng)一個(gè)進(jìn)程已經(jīng)打開了該文件,其內(nèi)容也不能刪除,當(dāng)進(jìn)程關(guān)閉時(shí),文件才會(huì)刪除。 remove,對(duì)于文件,功能和unlink相同,對(duì)于目錄,和rmdir相同。 rename,文件或目錄改名。,symlink和readl
48、ink函數(shù),創(chuàng)建軟鏈接文件 并不要求目標(biāo)文件已經(jīng)存在 并不需要位于同一個(gè)文件系統(tǒng)中 因?yàn)閛pen函數(shù)無法直接讀取軟件鏈接文件,可以使用readlink,創(chuàng)建目錄,mkdir 創(chuàng)建一個(gè)空目錄 mode參數(shù)指定權(quán)限 rmdir 刪除一個(gè)空目錄,讀目錄,DIR* opendir() 打開目錄,成功返回指針,失敗NULL struct dirent* readdir(DIR*) 讀目錄,返回第一個(gè)目錄項(xiàng) Dirent結(jié)構(gòu): struct dirent ino_t d_ino;/i-node號(hào) char d_name256;/文件名 rewinddir telldir seekdir,chdir、fch
49、dir、getcwd,chdir、fchdir 更改當(dāng)前工作目錄 工作目錄只是進(jìn)程的一個(gè)屬性,所以它只影響進(jìn)程本身 getcwd 獲取當(dāng)前工作目錄的絕對(duì)路徑,進(jìn)程控制,進(jìn)程和程序,進(jìn)程就是運(yùn)行中的程序。一個(gè)運(yùn)行著的程序,可能有多個(gè)進(jìn)程。進(jìn)程在操作系統(tǒng)中執(zhí)行特定的任務(wù)。 程序是存儲(chǔ)在磁盤上包含可執(zhí)行機(jī)器指令和數(shù)據(jù)的靜態(tài)實(shí)體。進(jìn)程或者任務(wù)是處于活動(dòng)狀態(tài)的計(jì)算機(jī)程序。,進(jìn)程分類,進(jìn)程一般分為交互進(jìn)程、批處理進(jìn)程和守護(hù)進(jìn)程三類。 守護(hù)進(jìn)程總是活躍的,一般是后臺(tái)運(yùn)行,守護(hù)進(jìn)程一般是由系統(tǒng)在開機(jī)時(shí)通過腳本自動(dòng)激活啟動(dòng)或超級(jí)管理用戶root來啟動(dòng)。,ps aux 查看進(jìn)程,顯示進(jìn)程的信息 USER進(jìn)程的屬主
50、; PID進(jìn)程的ID; PPID 父進(jìn)程; %CPU進(jìn)程占用的CPU百分比; %MEM占用內(nèi)存的百分比; NI 進(jìn)程的NICE值,數(shù)值大,表示較少占用CPU時(shí)間; VSZ 進(jìn)程虛擬大??; RSS 駐留中頁的數(shù)量; WCHAN TTY 終端ID,STAT 進(jìn)程狀態(tài) D Uninterruptible sleep (usually IO) R 正在運(yùn)行可中在隊(duì)列中可過行的; S 處于休眠狀態(tài); T 停止或被追蹤; W 進(jìn)入內(nèi)存交換(從內(nèi)核2.6開始無效); X 死掉的進(jìn)程(從來沒見過); Z 僵尸進(jìn)程; 優(yōu)先級(jí)高的進(jìn)程 N 優(yōu)先級(jí)較低的進(jìn)程 L 有些頁被鎖進(jìn)內(nèi)存; s 進(jìn)程的領(lǐng)導(dǎo)者(在它之下有子進(jìn)
51、程);,進(jìn)程描述符,每個(gè)進(jìn)程都有一個(gè)非負(fù)整形表示的唯一進(jìn)程ID 進(jìn)程ID是唯一的,但可以重用。當(dāng)一個(gè)進(jìn)程終止時(shí),其進(jìn)程ID就可以再次使用。 延遲重用法 getpid獲得進(jìn)程ID getppid獲得父進(jìn)程ID getuid獲得實(shí)際用戶ID geteuid獲得有效用戶ID getgid獲得實(shí)際組ID getegid 獲得有效組ID,創(chuàng)建進(jìn)程fork,fork 創(chuàng)建一個(gè)新進(jìn)程 出錯(cuò)返回-1 由fork函數(shù)創(chuàng)建的進(jìn)程叫子進(jìn)程(child proccess) 此函數(shù)調(diào)用一次,返回兩次。 分別在子進(jìn)和和父進(jìn)程中返回,子進(jìn)程中返回0,父進(jìn)程返回子進(jìn)程的PID 子進(jìn)程是父進(jìn)程的副本,子進(jìn)程獲得父進(jìn)程的數(shù)據(jù)空間
52、,堆和棧的副本,但子進(jìn)程共享父進(jìn)程的正文段 fork之后父子進(jìn)程會(huì)繼續(xù)執(zhí)行。 fork之后 父進(jìn)程先執(zhí)行還是子進(jìn)程先執(zhí)行不確定 fork時(shí),文件描述符也會(huì)被復(fù)制,那么兩個(gè)進(jìn)程可能會(huì)共享同一個(gè)文件表。,fork,fork失敗的原因 系統(tǒng)中有太多的進(jìn)程 實(shí)際用戶ID的進(jìn)程總數(shù)已經(jīng)超過系統(tǒng)限制。 fork的用法 一個(gè)父進(jìn)程希望復(fù)制自己,使父子進(jìn)程同時(shí)執(zhí)行不同的代碼段 一個(gè)進(jìn)程要執(zhí)行一個(gè)不同的程序,vfork,基本功能和fork相同 區(qū)別: vfork創(chuàng)建新進(jìn)程的主要目的是exec一個(gè)新程序。 vfork并不復(fù)制父進(jìn)程的地址空間,因?yàn)樽舆M(jìn)程會(huì)立即調(diào)用exec vfork保證子進(jìn)程先運(yùn)行,進(jìn)程終止的5種
53、正常情況,在main函數(shù)中執(zhí)行return 調(diào)用exit函數(shù),并不處理文件描述符,多進(jìn)程 調(diào)用_exit或_Exit. 進(jìn)程的最后一個(gè)線程執(zhí)行了返回語句 進(jìn)程的最后一個(gè)線程調(diào)用pthread_exit函數(shù),進(jìn)程的3種異常終止方式,調(diào)用abort,產(chǎn)生SIGABRT信號(hào) 進(jìn)程接收到某些信號(hào) 最后一個(gè)線程對(duì)“取消”請(qǐng)求做出響應(yīng),wait和waitpid函數(shù),當(dāng)一個(gè)進(jìn)程正?;虍惓=K止時(shí),內(nèi)核就向其父進(jìn)程發(fā)送SIGCHLD信號(hào)。父進(jìn)程可以忽略該信號(hào),或者提供一個(gè)該該信號(hào)的處理函數(shù)。默認(rèn)情況下,系統(tǒng)會(huì)忽略該信號(hào) 如果父進(jìn)程調(diào)用了wait或waitpid時(shí) 如果其子進(jìn)程都還在運(yùn)行,則阻塞 如果一個(gè)子進(jìn)程已
54、終止,正等待父進(jìn)程獲取其終止?fàn)顟B(tài),則取得該子進(jìn)程的終止?fàn)顟B(tài)立即返回 如果它沒有任何子進(jìn)程,則立即返回 區(qū)別 在一個(gè)子進(jìn)程終止前,wait使其調(diào)用者阻塞,而waitpid 很多選擇 如果一個(gè)子進(jìn)程已經(jīng)終止,并且是僵死進(jìn)程,wait會(huì)立即返回并取得該子進(jìn)程的狀態(tài),否則阻塞。,參數(shù)statloc,終止進(jìn)程的狀態(tài)將保存在此指針指向的位置,如果不關(guān)心狀態(tài),可置空。 得到的狀態(tài)由中的各個(gè)宏來查看。有四個(gè)互斥的宏用來查看進(jìn)程終止的原因,waitpid,如果進(jìn)程有幾個(gè)子進(jìn)程,那么要等待指定的進(jìn)程終止,可使用waitpid pid參數(shù) =-1,等待任意子進(jìn)程,與wait等效 0 等待指定子進(jìn)程 =0 等待其組I
55、D等于調(diào)用進(jìn)程組ID的任一子進(jìn)程 -1 等待其組ID等于pid絕對(duì)值的任一子進(jìn)程 Options參數(shù)可以為0,或是以下參數(shù),參數(shù)可“或”疊加,exec函數(shù),exec函數(shù)會(huì)用新程序完全替代掉現(xiàn)有程序,并開始從main函數(shù)執(zhí)行。 exec并不創(chuàng)建新的進(jìn)程,所以pid并未改變 exec只是用一個(gè)全新的程序替換了當(dāng)前進(jìn)程的正文、數(shù)據(jù)、堆和棧。 有6種不同的exec函數(shù)可供使用 int execl(const char *path, const char *arg, .); int execv(const char *path, char *const argv); int execlp(const c
56、har *file, const char *arg, .); int execle(const char *path, const char *arg, ., char * const envp); int execve(const char *path, const char *arg, char * const envp); int execvp(const char *file, char *const argv);,區(qū)別,第一個(gè)參數(shù)是路徑名或文件名,當(dāng)是文件名時(shí),如果其中包含/則為路徑名,否則查找PATH環(huán)境變量獲取文件 參數(shù)表的傳遞,l表示list,v表示vector. 以e結(jié)尾的
57、兩個(gè)函數(shù)可以傳遞一個(gè)指向環(huán)境字符串指針數(shù)據(jù)的指針。,system函數(shù),ISO C定義了此函數(shù) 如果參數(shù)是空,返回非零值。此特性經(jīng)常用來測(cè)試平臺(tái)是否支持此函數(shù) 函數(shù)本質(zhì)上調(diào)用了fork、exec和waitpid,返回值如 如果fork失敗或waitpid出錯(cuò),則返回-1 如果exec失敗,如果執(zhí)行了exit(127) 如果都成功,返回shell的終止?fàn)顟B(tài),見waitpid 使用system而不是fork和exec的優(yōu)點(diǎn)是,system 進(jìn)行了所需的各種出錯(cuò)處理,以及各種信號(hào)處理。,信號(hào),信號(hào)概念,信號(hào)是軟件中斷。它即可以作為進(jìn)程間通信的一種機(jī)制,更重要的是,信號(hào)總是中斷一個(gè)進(jìn)程的正常運(yùn)行,它更多
58、地被用于處理一些非正常情況。ctrl+c就是一個(gè)信號(hào) 信號(hào)是異步的,進(jìn)程并不知道信號(hào)什么時(shí)候到達(dá)。 進(jìn)程既可以處理信號(hào),也可以發(fā)送信號(hào)給特定進(jìn)程。 每個(gè)信號(hào)都有一個(gè)名字,這些名字都以SIG開頭。例如:SIGABRT是進(jìn)程異常終止信號(hào)。,信號(hào)的來源,硬件異常產(chǎn)生信號(hào):除數(shù)為0、無效的存儲(chǔ)訪問等等。這些條件通常由硬件檢測(cè)到,并將其通知內(nèi)核。然后內(nèi)核為該條件發(fā)生時(shí)正在運(yùn)行的進(jìn)程產(chǎn)生適當(dāng)?shù)男盘?hào)。 軟件產(chǎn)生異常信號(hào),可以用kill、raise、alarm、setitimer和 sigqueue產(chǎn)生信號(hào)。,信號(hào)的種類,不可靠的信號(hào):Linux信號(hào)機(jī)制基本上是從Unix系統(tǒng)中繼承過來的。早期Unix系統(tǒng)中的
59、信號(hào)機(jī)制比較簡(jiǎn)單和原始,后來在實(shí)踐中暴露出一些問題,因此,把那些建立在早期機(jī)制上的信號(hào)叫做“不可靠信號(hào)”,信號(hào)值小于SIGRTMIN的叫不可靠信號(hào)(131)。 每次信號(hào)處理后,該信號(hào)對(duì)應(yīng)的處理函數(shù)會(huì)恢復(fù)到默認(rèn)值。但現(xiàn)代的Linux已經(jīng)對(duì)其進(jìn)行了改進(jìn),信號(hào)處理函數(shù)一直是用戶指定的或者是系統(tǒng)默認(rèn)的。 信號(hào)可能丟失。 不可靠信號(hào)不支持信號(hào)排隊(duì),同一個(gè)信號(hào)產(chǎn)生多次,只要程序還未處理該信號(hào),那么實(shí)際只處理此信號(hào)一次。,信號(hào)的種類,可靠信號(hào):信號(hào)值位于SIGRTMIN和SIGRTMAX之間的信號(hào)都是可靠信號(hào),可靠信號(hào)克服了信號(hào)可能丟失的問題 。 實(shí)時(shí)信號(hào)與非實(shí)時(shí)信號(hào):Linux目前定義了64種信號(hào)(將來可能會(huì)擴(kuò)展),前面32種為非實(shí)時(shí)信號(hào),后32種為實(shí)時(shí)信號(hào)。非實(shí)時(shí)信號(hào)都不支持排隊(duì),都是不可靠信號(hào),實(shí)時(shí)信號(hào)都支持排隊(duì),都是可靠信號(hào)。 信號(hào)排隊(duì)意味著無論產(chǎn)生多少次信號(hào),信號(hào)處理函數(shù)就會(huì)被調(diào)用同樣的次數(shù)。,Linux系統(tǒng)信號(hào),Linux系統(tǒng)信號(hào),Linux系統(tǒng)信號(hào),信號(hào)處理流程,信號(hào)處理取決于Linux內(nèi)核屏蔽字。當(dāng)信號(hào)是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 北師大版數(shù)學(xué)七年級(jí)上冊(cè)課程標(biāo)準(zhǔn)落實(shí)計(jì)劃
- 幼兒園財(cái)務(wù)崗位責(zé)任與職責(zé) 他
- 2024-2025小學(xué)語文教研組課程優(yōu)化計(jì)劃
- “雙減”背景下城市中小學(xué)課堂教學(xué)質(zhì)量心得體會(huì)
- 監(jiān)理安全事故處理個(gè)人總結(jié)范文
- 家庭貧困學(xué)生控輟保學(xué)措施
- 初中班主任學(xué)情分析改進(jìn)計(jì)劃
- 住院期間患者VTE風(fēng)險(xiǎn)評(píng)分流程他
- 微信婚慶服務(wù)營銷活動(dòng)方案流程他
- 以少年文學(xué)為翼翱翔心理健康藍(lán)天:初中生心理素質(zhì)培養(yǎng)新路徑
- 醫(yī)院保潔服務(wù)投標(biāo)方案(技術(shù)方案)
- 設(shè)立財(cái)稅管理咨詢公司實(shí)施方案
- 車間產(chǎn)能分析報(bào)告
- 安全班組管理的基石
- 先兆流產(chǎn)護(hù)理課件
- 《計(jì)算機(jī)控制系統(tǒng)》李正軍第4版 習(xí)題答案
- 汽車耐腐蝕標(biāo)準(zhǔn)
- 眼視光應(yīng)用光學(xué)題庫及答案
- 機(jī)器設(shè)備維護(hù)保養(yǎng)記錄表
- 小學(xué)音體美學(xué)科教師考核辦法
- 深基坑工程培訓(xùn)課件
評(píng)論
0/150
提交評(píng)論