第7章 Linux編程環(huán)境之進(jìn)程控制與進(jìn)程間通信_(tái)第1頁(yè)
第7章 Linux編程環(huán)境之進(jìn)程控制與進(jìn)程間通信_(tái)第2頁(yè)
第7章 Linux編程環(huán)境之進(jìn)程控制與進(jìn)程間通信_(tái)第3頁(yè)
第7章 Linux編程環(huán)境之進(jìn)程控制與進(jìn)程間通信_(tái)第4頁(yè)
第7章 Linux編程環(huán)境之進(jìn)程控制與進(jìn)程間通信_(tái)第5頁(yè)
已閱讀5頁(yè),還剩106頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第7章 第1頁(yè)第第7章章 進(jìn)程控制與進(jìn)程間通信進(jìn)程控制與進(jìn)程間通信第7章 第2頁(yè)7.1 進(jìn)程控制進(jìn)程控制第7章 第3頁(yè)進(jìn)程與程序進(jìn)程與程序n 程序程序u指令和數(shù)據(jù)的集合 u存放在磁盤(pán)上的一個(gè)普通文件里u文件的i節(jié)點(diǎn)中標(biāo)為可執(zhí)行,內(nèi)容符合系統(tǒng)要求n 進(jìn)程進(jìn)程u包括指令段、用戶數(shù)據(jù)段和系統(tǒng)數(shù)據(jù)段的執(zhí)行環(huán)境n 進(jìn)程和程序的關(guān)系進(jìn)程和程序的關(guān)系u程序用于初始化進(jìn)程的指令段和用戶數(shù)據(jù)段,初始化后,進(jìn)程和初始化它的程序之間無(wú)聯(lián)系u進(jìn)程運(yùn)行時(shí)磁盤(pán)上的程序文件不可修改/刪除u同時(shí)運(yùn)行的多個(gè)進(jìn)程可由同一程序初始化得到,進(jìn)程之間沒(méi)什么聯(lián)系。內(nèi)核通過(guò)安排它們共享指令段以節(jié)省內(nèi)存,但這種安排對(duì)用戶來(lái)說(shuō)是透明的第7章

2、第4頁(yè)進(jìn)程的組成部分進(jìn)程的組成部分(1) 四部分:指令段,數(shù)據(jù)段,堆棧段和系統(tǒng)數(shù)據(jù)四部分:指令段,數(shù)據(jù)段,堆棧段和系統(tǒng)數(shù)據(jù)n 指令段指令段(Text)u程序的CPU指令代碼,包括:主程序和子程序編譯后的CPU指令代碼,以及調(diào)用的庫(kù)函數(shù)代碼u指令段的大小固定不變,只讀n 用戶數(shù)據(jù)段用戶數(shù)據(jù)段u全局變量,靜態(tài)(static)變量,字符串常數(shù)u允許數(shù)據(jù)段增長(zhǎng)和縮小,實(shí)現(xiàn)內(nèi)存的動(dòng)態(tài)分配系統(tǒng)調(diào)用sbrk()允許編程調(diào)整數(shù)據(jù)段的大小內(nèi)存管理庫(kù)函數(shù),如:malloc(),free()第7章 第5頁(yè)進(jìn)程的組成部分進(jìn)程的組成部分(2)n 用戶堆棧段用戶堆棧段u程序執(zhí)行所需要的堆棧空間,實(shí)現(xiàn)函數(shù)的調(diào)用用于保存子程

3、序返回地址在函數(shù)和被調(diào)函數(shù)之間傳遞參數(shù)函數(shù)體內(nèi)部定義的變量(靜態(tài)變量除外)umain函數(shù)得到的命令行參數(shù)以及環(huán)境參數(shù)存放在堆棧的最底部main函數(shù)運(yùn)行之前,這些部分就已經(jīng)被系統(tǒng)初始化u堆棧段的動(dòng)態(tài)增長(zhǎng)與增長(zhǎng)限制n 系統(tǒng)數(shù)據(jù)段系統(tǒng)數(shù)據(jù)段u上述三部分在進(jìn)程私有的獨(dú)立的邏輯地址空間內(nèi)u系統(tǒng)數(shù)據(jù)段是內(nèi)核內(nèi)的數(shù)據(jù),每個(gè)進(jìn)程對(duì)應(yīng)一套包括頁(yè)表和進(jìn)程控制塊PCB第7章 第6頁(yè)進(jìn)程邏輯地址空間的布局進(jìn)程邏輯地址空間的布局 指令段初始化的只讀型數(shù)據(jù)初始化的讀寫(xiě)型數(shù)據(jù)未初始化的數(shù)據(jù)動(dòng)態(tài)分配得到的內(nèi)存命令行參數(shù)和環(huán)境參數(shù)工作堆棧用戶堆棧(空閑區(qū))數(shù)據(jù)段指令段低地址高地址棧底棧頂增長(zhǎng)方向第7章 第7頁(yè)進(jìn)程的系統(tǒng)數(shù)據(jù)進(jìn)程

4、的系統(tǒng)數(shù)據(jù)在UNIX內(nèi)核中,含有進(jìn)程的屬性,包括:u頁(yè)表u進(jìn)程狀態(tài),優(yōu)先級(jí)信息u核心堆棧u當(dāng)前目錄(記錄了當(dāng)前目錄的i-節(jié)點(diǎn)),根目錄u打開(kāi)的文件描述符表uumask值u進(jìn)程PID,PPIDu進(jìn)程主的實(shí)際UID/GID,有效UID/GIDu進(jìn)程組組號(hào)第7章 第8頁(yè)user結(jié)構(gòu)和結(jié)構(gòu)和proc結(jié)構(gòu)結(jié)構(gòu)n 進(jìn)程進(jìn)程PCB被分為被分為user結(jié)構(gòu)和結(jié)構(gòu)和proc結(jié)構(gòu)兩部分結(jié)構(gòu)兩部分uuser結(jié)構(gòu)(約5000字節(jié)),進(jìn)程運(yùn)行時(shí)才需要的數(shù)據(jù)在user結(jié)構(gòu)核心態(tài)堆棧占用了較多空間uproc結(jié)構(gòu)(約300字節(jié)),進(jìn)程不運(yùn)行時(shí)也需要的管理信息存于proc結(jié)構(gòu)u用戶程序不能直接存取和修改進(jìn)程的系統(tǒng)數(shù)據(jù)u系統(tǒng)調(diào)用

5、可用來(lái)訪問(wèn)或修改這些屬性chdir, umask,open, closesetpgrp, getpid, getppid第7章 第9頁(yè)進(jìn)程的基本狀態(tài)進(jìn)程的基本狀態(tài)n 基本狀態(tài)基本狀態(tài)u進(jìn)程創(chuàng)建之后,主要有運(yùn)行狀態(tài)和睡眠狀態(tài)(也叫阻塞狀態(tài),等待狀態(tài),掛起狀態(tài),等等)u內(nèi)核總是在分時(shí)處理運(yùn)行狀態(tài)的進(jìn)程,而不顧那些處于睡眠狀態(tài)的進(jìn)程u睡眠狀態(tài)的進(jìn)程,在條件滿足后轉(zhuǎn)化為運(yùn)行狀態(tài)u進(jìn)程在睡眠時(shí),不占用CPU時(shí)間注意:在編程時(shí),程序不要處于忙等待狀態(tài)注意:在編程時(shí),程序不要處于忙等待狀態(tài)第7章 第10頁(yè)進(jìn)程的調(diào)度進(jìn)程的調(diào)度n 調(diào)度優(yōu)先級(jí)調(diào)度優(yōu)先級(jí)u內(nèi)核將可運(yùn)行進(jìn)程按優(yōu)先級(jí)調(diào)度,高優(yōu)先級(jí)進(jìn)程優(yōu)先u進(jìn)程的優(yōu)先

6、級(jí)總在不停地發(fā)生變化u處于睡眠狀態(tài)的進(jìn)程一旦被叫醒后,被賦以高優(yōu)先級(jí),以保證人機(jī)會(huì)話操作和其它外設(shè)的響應(yīng)速度u用戶程序用nice()系統(tǒng)調(diào)用有限地調(diào)整進(jìn)程的優(yōu)先級(jí)第7章 第11頁(yè)用戶程序庫(kù)函數(shù)scanf() . len=read(.); .ttyintr() . if (.) wakeup(.); .read() . if(.)ttyread(.); .系統(tǒng)調(diào)用驅(qū)動(dòng)程序(下半部分)驅(qū)動(dòng)程序(上半部分)ttyread() . sleep(.); .main() . scanf(.); .睡眠狀態(tài)硬件中斷喚醒進(jìn)程進(jìn)程調(diào)度用戶態(tài)核心態(tài)scanf(%d, &n);程序在串口終端上執(zhí)行時(shí)操作員輸入程序在

7、串口終端上執(zhí)行時(shí)操作員輸入756然后按下回車(chē)然后按下回車(chē)第7章 第12頁(yè)time:進(jìn)程執(zhí)行的時(shí)間進(jìn)程執(zhí)行的時(shí)間n 進(jìn)程執(zhí)行時(shí)間包括進(jìn)程執(zhí)行時(shí)間包括u睡眠時(shí)間,CPU時(shí)間(用戶時(shí)間和系統(tǒng)時(shí)間)u外部命令/usr/bin/timeuB-shell和C-shell都有個(gè)內(nèi)部命令time/usr/bin/time find /usr -name *.c -printReal 6.06User 0.36System 2.13uC-shell: time find /usr -name *.h -print0.4u 6.2s 0:10 61% 4+28k 0+0io 0pf+0wn 與與CPU時(shí)間有關(guān)的命

8、令時(shí)間有關(guān)的命令vmstat$ vmstat 10 procs memory swap io system cpu r b w swpd free buff cache si so bi bo in cs us sy id 0 0 0 0 55916 6128 38156 0 0 439 118 146 180 8 15 76 0 0 0 0 55252 6160 38160 0 0 0 32 112 54 26 1 73第7章 第13頁(yè)系統(tǒng)調(diào)用系統(tǒng)調(diào)用times()n 系統(tǒng)調(diào)用系統(tǒng)調(diào)用times()當(dāng)前進(jìn)程CPU時(shí)間,已結(jié)束子進(jìn)程占用過(guò)的CPU時(shí)間clock_t times(struct t

9、ms *buf);struct tms clock_t tms_utime; /* user CPU time */ clock_t tms_stime; /* system CPU time */ clock_t tms_cutime; /* user CPU time, terminated children */ clock_t tms_cstime; /* system CPU time, terminated children */;n clock()u返回times()的四個(gè)CPU時(shí)間的總和。單位是1/CLOCKS_PER_SEC秒n getrusage()函數(shù),函數(shù),times(

10、)函數(shù)的升級(jí)版本函數(shù)的升級(jí)版本u返回CPU時(shí)間,還返回表示資源使用狀況的另外14個(gè)值,包括內(nèi)存使用情況,I/O次數(shù),進(jìn)程切換次數(shù)第7章 第14頁(yè)與時(shí)間有關(guān)的函數(shù)與時(shí)間有關(guān)的函數(shù)n 標(biāo)準(zhǔn)函數(shù)庫(kù)中標(biāo)準(zhǔn)函數(shù)庫(kù)中time():獲得當(dāng)前時(shí)間坐標(biāo):獲得當(dāng)前時(shí)間坐標(biāo)u坐標(biāo)0為1970年1月1日零點(diǎn),單位:秒ut=time(0);和time(&t);都會(huì)使t值為當(dāng)前時(shí)間坐標(biāo)n 函數(shù)函數(shù)gettimeofday()u獲得當(dāng)前時(shí)間坐標(biāo),坐標(biāo)的0是1970年1月1日零點(diǎn)u可以精確到微秒s(10-6秒)n localtime()u將坐標(biāo)值轉(zhuǎn)換為本地時(shí)區(qū)的年月日時(shí)分秒n mktimeu將年月日時(shí)分秒轉(zhuǎn)換為坐標(biāo)值n ct

11、ime()和和asctime()u坐標(biāo)值和年月日時(shí)分秒轉(zhuǎn)換為可讀字符串第7章 第15頁(yè)忙等待忙等待n 多任務(wù)系統(tǒng)中多任務(wù)系統(tǒng)中“忙等待忙等待”的程序是不可取的的程序是不可取的 1 #include 2 main(int argc, char *argv) 3 4 unsigned char buf1024; 5 int len, fd; 6 if ( (fd = open(argv1, O_RDONLY) 0)13 write(1, buf, len);14 15 u程序14行前增加sleep(1):1秒定時(shí)輪詢uselect()調(diào)用可將睡眠時(shí)間設(shè)為10毫秒級(jí)精度第7章 第16頁(yè)fork:創(chuàng)建

12、新進(jìn)程:創(chuàng)建新進(jìn)程n 功能功能ufork系統(tǒng)調(diào)用是創(chuàng)建新進(jìn)程的唯一方式u原先的進(jìn)程稱做“父進(jìn)程”,新創(chuàng)建進(jìn)程被稱作“子進(jìn)程”u完全復(fù)制:新進(jìn)程的指令,用戶數(shù)據(jù)段,堆棧段u部分復(fù)制:系統(tǒng)數(shù)據(jù)段n fork返回值:父子進(jìn)程都收到返回值,但不相同返回值:父子進(jìn)程都收到返回值,但不相同u返回值很關(guān)鍵,它用于區(qū)分父進(jìn)程(返回值0,是子進(jìn)程的PID)和子進(jìn)程(返回值=0),失敗時(shí)返回-1n 內(nèi)核實(shí)現(xiàn)內(nèi)核實(shí)現(xiàn)u創(chuàng)建新的proc結(jié)構(gòu),復(fù)制父進(jìn)程環(huán)境(包括user結(jié)構(gòu)和內(nèi)存資源)給子進(jìn)程u父子進(jìn)程可以共享程序和數(shù)據(jù)(例如:copy-on-write技術(shù)),但是系統(tǒng)核心的這些安排,對(duì)程序員透明第7章 第17頁(yè)fo

13、rk舉例舉例(1)執(zhí)行結(jié)果執(zhí)行結(jié)果1 ./fork1: BEGIN2 a+b=303 a+b=2304 ./fork1: END3 a+b=2304 ./fork1: ENDint a;int main(int argc, char *argv) int b; printf(1 %s: BEGINn, argv0); a = 10; b = 20; printf(2 a+b=%dn, a + b); fork(); a += 100; b += 100; printf(3 a+b=%dn, a + b); printf(4 %s: ENDn, argv0);第7章 第18頁(yè)fork舉例舉例(2

14、)執(zhí)行結(jié)果執(zhí)行結(jié)果HelloPID=18378 ppid=18377, a=6ByePID=18377 child=18378, a=6Byemain() int a, ret; printf(Hellon); a = 3; ret = fork(); a += 3; if (ret 0) printf(PID=%d child=%d, a=%dn, getpid(), ret, a); else if (ret = 0) printf(PID=%d ppid=%d, a=%dn, getpid(), getppid(), a); else perror(Create new process)

15、; printf(Byen); 第7章 第19頁(yè)命令命令psn 功能功能u查閱進(jìn)程狀態(tài)(process status)(實(shí)際上就是將內(nèi)核中proc和user數(shù)組的內(nèi)容有選擇地打印出來(lái))n 選項(xiàng)選項(xiàng)u用于控制列表的行數(shù)(進(jìn)程范圍)和列數(shù)(每進(jìn)程列出的屬性內(nèi)容)u無(wú)選項(xiàng):只列出在當(dāng)前終端上啟動(dòng)的進(jìn)程列出的項(xiàng)目有:PID,TTY,TIME,COMMANDue選項(xiàng):列出系統(tǒng)中所有的進(jìn)程(進(jìn)程范圍)uf選項(xiàng):以full格式列出每一個(gè)進(jìn)程(控制列的數(shù)目)ul選項(xiàng):以long格式列出每一個(gè)進(jìn)程(控制列的數(shù)目)第7章 第20頁(yè)命令命令ps舉例舉例例:例:ps -efps -ef命令的輸出命令的輸出 UID P

16、ID PPID C STIME TTY TIME COMMANDroot 0 0 0 16:11:14 ? 0:00 schedroot 1 0 0 16:11:14 ? 0:01 /etc/init root 2 0 0 16:11:14 ? 0:00 vhandroot 3 0 0 16:11:14 ? 0:00 bdflushroot 6547 335 0 16:15:05 01 0:00 server 4 1 root 175 1 0 16:11:14 ? 0:00 inetd root 173 1 0 16:11:14 ? 0:00 syslogd root 296 1 0 16:1

17、1:21 ? 0:00 /tcb/files/no_luid/sdd root 6551 291 80 16:17:16 08 0:37 busy_check root 335 1 0 16:11:31 01 0:00 server_ctl root 337 1 0 16:11:33 01 0:05 server_ap root 353 1 0 16:12:01 12 0:00 client_ctl root 356 295 0 16:12:07 12 0:04 client_ap 1403第7章 第21頁(yè)命令命令ps列出的進(jìn)程屬性列出的進(jìn)程屬性u(píng)UID:用戶ID(注冊(cè)名)

18、uPID:進(jìn)程IDuC:CPU占用指數(shù):最近一段時(shí)間(秒級(jí)別)進(jìn)程占用CPU情況。不同系統(tǒng)算法不同,例如:正占CPU進(jìn)程10ms加1,所有進(jìn)程1秒衰減一半uPPID:父進(jìn)程的PIDuSTIME:?jiǎn)?dòng)時(shí)間uSZ:進(jìn)程邏輯內(nèi)存大小(Size)uTTY:終端的名字 uCOMMAND:命令名uWCHAN:進(jìn)程睡眠通道(Wait Channel)uTIME:累計(jì)執(zhí)行時(shí)間(占用CPU的時(shí)間) uPRI:優(yōu)先級(jí)uS:狀態(tài),S(Sleep),R(Run), Z(Zombie)第7章 第22頁(yè)命令行參數(shù)和環(huán)境參數(shù)命令行參數(shù)和環(huán)境參數(shù)n 位于進(jìn)程堆棧底部的初始化數(shù)據(jù)位于進(jìn)程堆棧底部的初始化數(shù)據(jù)n 訪問(wèn)命令行參數(shù)的

19、方法(訪問(wèn)命令行參數(shù)的方法(argc,argv)u查閱進(jìn)程狀態(tài)(process status)(實(shí)際上就是將內(nèi)核中proc和user數(shù)組的內(nèi)容有選擇地打印出來(lái))n 訪問(wèn)環(huán)境參數(shù)的三種方法訪問(wèn)環(huán)境參數(shù)的三種方法u通過(guò)C庫(kù)定義的外部變量environumain函數(shù)的第三個(gè)參數(shù)uGetenv庫(kù)函數(shù)調(diào)用第7章 第23頁(yè)訪問(wèn)環(huán)境參數(shù)的三種方法訪問(wèn)環(huán)境參數(shù)的三種方法main() extern char *environ; char *p; p = environ; while (*p) printf(”%sn”, *p+);main(int argc, char *argv, char *env) cha

20、r *p; p = env; while (*p) printf(”%sn”, *p+);main() char *p; p=getenv(”HOME”); if (p) printf (”%sn”);n 訪問(wèn)環(huán)境參數(shù)的三種方法訪問(wèn)環(huán)境參數(shù)的三種方法第7章 第24頁(yè)exec系統(tǒng)調(diào)用系統(tǒng)調(diào)用n 功能功能u用一個(gè)指定的程序文件,重新初始化一個(gè)進(jìn)程u可指定新的命令行參數(shù)和環(huán)境參數(shù)(初始化堆棧底部)uexec不創(chuàng)建新進(jìn)程,只是將當(dāng)前進(jìn)程重新初始化了指令段和用戶數(shù)據(jù)段,堆棧段以及CPU的PC指針n 6種格式種格式exec系統(tǒng)調(diào)用系統(tǒng)調(diào)用uexec前綴,后跟一至兩個(gè)字母 llist,vvector,een

21、v,ppathul與v:指定命令行參數(shù)的兩種方式,l以表的形式,v要事先組織成一個(gè)指針數(shù)組ue:需要指定envp來(lái)初始化進(jìn)程。up:使用環(huán)境變量PATH查找可執(zhí)行文件u六種格式的區(qū)別:不同的參數(shù)方式初始化堆棧底部第7章 第25頁(yè)exec系統(tǒng)調(diào)用格式系統(tǒng)調(diào)用格式int execl(char *file,char *arg0,char *arg1,.,0);int execv(char *file, char *argv);int execle(char *file, char *arg0, char *arg1, ., 0, char *envp);int execve(char *file,

22、char *argv, char* envp);int execlp(char *file, char *arg0, char *arg1, ., 0);int execvp(char *file, char *argv);第7章 第26頁(yè)“僵尸僵尸”進(jìn)程進(jìn)程n “僵尸僵尸”進(jìn)程進(jìn)程(zombie或或defunct)u進(jìn)程生命期結(jié)束時(shí)的特殊狀態(tài)系統(tǒng)已經(jīng)釋放了進(jìn)程占用的包括內(nèi)存在內(nèi)的系統(tǒng)資源,但仍在內(nèi)核中保留進(jìn)程的部分?jǐn)?shù)據(jù)結(jié)構(gòu),記錄進(jìn)程的終止?fàn)顟B(tài),等待父進(jìn)程來(lái)“收尸”父進(jìn)程的“收尸”動(dòng)作完成之后,“僵尸”進(jìn)程不再存在u僵尸進(jìn)程占用資源很少,僅占用內(nèi)核進(jìn)程表資源過(guò)多的僵尸進(jìn)程會(huì)導(dǎo)致系統(tǒng)有限數(shù)目的進(jìn)

23、程表被用光u孤兒進(jìn)程第7章 第27頁(yè)wait系統(tǒng)調(diào)用系統(tǒng)調(diào)用n 功能功能u等待進(jìn)程的子進(jìn)程終止u如果已經(jīng)有子進(jìn)程終止,則立即返回n 函數(shù)原型函數(shù)原型#include #include pid_t wait(int *stat_loc); 函數(shù)返回值為已終止的子進(jìn)程PIDu例 int status, pid; pid = wait(&status); status中含有子進(jìn)程終止的原因 TERMSIG(status)為被殺信號(hào) EXITSTATUS(status)為退出碼n waitpid()和和wait3() : wait系統(tǒng)調(diào)用的升級(jí)版本系統(tǒng)調(diào)用的升級(jí)版本第7章 第28頁(yè)字符串庫(kù)函數(shù)字符串庫(kù)

24、函數(shù)strtokchar char * *strtok(char strtok(char * *str, char , char * *tokens) )功能: 返回第一個(gè)單詞的首字節(jié)指針20 09 77 68 6f 20 20 61 6d 20 69 0a 0020 09 77 68 6f 20 20 61 6d 20 69 0a 00 t w h o a m i n 0s執(zhí)行執(zhí)行p=strtok(s, tn);p=strtok(s, tn);之后之后20 09 77 68 6f20 09 77 68 6f 0000 20 61 6d 20 69 0a 0020 61 6d 20 69 0a

25、 00s20 09 77 68 6f 00 20 61 6d 20 09 77 68 6f 00 20 61 6d 0000 69 0a 00 69 0a 00sp執(zhí)行執(zhí)行p=strtok(NULL, tn);p=strtok(NULL, tn);之后之后20 09 77 68 6f 00 20 61 6d20 09 77 68 6f 00 20 61 6d 0000 69 69 0000 00 00s執(zhí)行執(zhí)行p=strtok(NULL, tn);p=strtok(NULL, tn);之后之后pp第7章 第29頁(yè)最簡(jiǎn)單的最簡(jiǎn)單的shell: xsh0main() char buf256, *c

26、md, *argv100; int n, sv; for(;) printf(= ); if (fgets(buf, sizeof(buf), stdin) = NULL) exit(0); cmd = strtok(buf, tn); if (cmd != NULL) continue; if (strcmp(cmd, exit) = 0) exit(0); n = 0; argvn+ = cmd; while (argvn+ = strtok(NULL, tn); if (fork() = 0) execvp(cmd, argv); fprintf(stderr, * Bad comman

27、dn); exit(1); wait(&sv); 第7章 第30頁(yè)執(zhí)行執(zhí)行xsh0= who am iwho am iroot ttyp0 Nov 29 09:56= ps -fps -f UID PID PPID C STIME TTY TIME CMDroot 1012 1011 0 09:56:00 ttyp0 00:00:00 login -c -proot 1020 1012 0 09:56:14 ttyp0 00:00:00 -cshroot 1060 1020 2 10:36:37 ttyp0 00:00:00 xsh0root 1062 1060 4 10:36:46 ttyp

28、0 00:00:00 ps -f= ls -l ls -l * *.c.cls: *.c not found: No such file or directory (error 2)= mmxmmx* Bad command= ls -l xsh0ls -l xsh0-rwxr-r- 1 root other 43417 Dec 1 1998 xsh0= exitexit第7章 第31頁(yè)system:運(yùn)行一個(gè)命令:運(yùn)行一個(gè)命令 int system(char *string);n 庫(kù)函數(shù)system執(zhí)行用字符串傳遞的shell命令,可使用管道符和重定向n 庫(kù)函數(shù)system()是利用系統(tǒng)調(diào)用f

29、ork,exec,wait實(shí)現(xiàn)的第7章 第32頁(yè)system應(yīng)用舉例應(yīng)用舉例 #include main() char fname256, cmd256, buf256; FILE *f; tmpnam(fname); sprintf(cmd, netstat -rn %s, fname); printf(Execute %sn, cmd); system(cmd); f = fopen(fname, r); while (fgets(buf, sizeof buf, f) printf(%s, buf); fclose(f); printf(Remove file %sn, fname);

30、unlink(fname);第7章 第33頁(yè)7.2 進(jìn)程與文件描述符進(jìn)程與文件描述符第7章 第34頁(yè)活動(dòng)文件目錄活動(dòng)文件目錄AFDn 磁盤(pán)文件目錄磁盤(pán)文件目錄(分兩級(jí)分兩級(jí))u文件名,i節(jié)點(diǎn)n 活動(dòng)文件目錄活動(dòng)文件目錄(分三級(jí)分三級(jí))u文件描述符表FDT:每進(jìn)程一張,user結(jié)構(gòu)中user結(jié)構(gòu)中整型數(shù)組u_ofile記錄進(jìn)程打開(kāi)的文件文件描述符fd是u_ofile數(shù)組的下標(biāo)u系統(tǒng)文件表SFT:整個(gè)核心一張,file結(jié)構(gòu) struct file char f_flag; /* 讀、寫(xiě)操作要求 */ char f_count; /* 引用計(jì)數(shù) */ int f_inode; /* 內(nèi)核中inode

31、數(shù)組的下標(biāo) */ long f_offset2; /* 文件讀/寫(xiě)位置指針 */ ;u活動(dòng)i節(jié)點(diǎn)表:整個(gè)核心一張,inode結(jié)構(gòu)內(nèi)存中inode表是外存中inode的緩沖 第7章 第35頁(yè)活動(dòng)文件目錄活動(dòng)文件目錄AFD(圖圖)0 01 12 23 3FDTFDT進(jìn)程進(jìn)程A A0 01 12 23 3進(jìn)程進(jìn)程B B0 01 12 23 3進(jìn)程進(jìn)程C CSFTSFTInodeInode第7章 第36頁(yè)文件描述符的繼承與關(guān)閉文件描述符的繼承與關(guān)閉n fork創(chuàng)建的子進(jìn)程繼承父進(jìn)程的文件描述符表創(chuàng)建的子進(jìn)程繼承父進(jìn)程的文件描述符表n 父進(jìn)程在父進(jìn)程在fork前打開(kāi)的文件,父子進(jìn)程有相同的前打開(kāi)的文件,

32、父子進(jìn)程有相同的文件偏移文件偏移父進(jìn)程父進(jìn)程父進(jìn)程父進(jìn)程子進(jìn)程子進(jìn)程forkfork前前forkfork后后第7章 第37頁(yè)例例:文件描述符的繼承與關(guān)閉文件描述符的繼承與關(guān)閉(1)#include void main() int fd; static char *str = F1:ABCDn; fd = open(abc, O_CREAT | O_WRONLY, 0666); write(fd, str, strlen(str); if (fork() 0) write(fd, str, strlen(str); close(fd); else char fdstr16; sprintf(fd

33、str, %d, fd); execlp(f2, f2, fdstr, 0); printf(failed to start f2n); exit(0); 第7章 第38頁(yè)例例:文件描述符的繼承與關(guān)閉文件描述符的繼承與關(guān)閉(2)n文件文件f2.cf2.cint main(int argc, char *argv) int fd; static char *str=F2:WXYZn; fd = strtol(argv1, 0, 0); write(fd, str, strlen(str); close(fd);第7章 第39頁(yè)close-on-exec標(biāo)志標(biāo)志n 文件文件close-on-exe

34、c標(biāo)志標(biāo)志u文件描述符fd設(shè)置了close-on-exec標(biāo)志,執(zhí)行exec系統(tǒng)調(diào)用時(shí),系統(tǒng)會(huì)自動(dòng)關(guān)閉這些文件n 函數(shù)函數(shù)#include int fcntl (fd, cmd, arg);cmd: F_GETFD 獲取文件fd的控制字 控制字的比特0(FD_CLOEXEC): close-on-exec標(biāo)志位 flag = fcntl(fd, F_GETFD, 0);cmd: F_SETFD 設(shè)置文件fd的控制字 fcntl(fd, F_SETFD, flag);n 例例flags = fcntl(fd, F_GETFD, 0);flags |= FD_CLOEXEC;fcntl(fd, F

35、_SETFD, flags);第7章 第40頁(yè)文件描述符的復(fù)制文件描述符的復(fù)制n 系統(tǒng)調(diào)用系統(tǒng)調(diào)用 int dup2(int fd1, int fd2);n 功能功能復(fù)制文件描述符fd1到fd2ufd2可以是空閑的文件描述符u如果fd2是已打開(kāi)文件,則關(guān)閉已打開(kāi)文件fd2fd2fd1fd1第7章 第41頁(yè)xsh1:輸入輸出重定向輸入輸出重定向(1) char buf256, *cmd, *argv100, *infile, *outfile; int n, sv; for (;) printf(= ); if (fgets(buf, sizeof(buf), stdin) = NULL) ex

36、it(0); infile = strstr(buf, ); if (infile) *infile = 0; infile = strtok(infile + 1, tn); if (outfile) *outfile = 0; outfile = strtok(outfile + 1, tn); cmd = strtok(buf, tn); if (cmd = NULL) continue; if(strcmp(cmd,exit)=0) exit(0); n=0; argvn+=cmd; while(argvn+=strtok(NULL, tn); 第7章 第42頁(yè)xsh1:輸入輸出重定向

37、輸入輸出重定向(2) if (fork() = 0) int fd0 = -1, fd1 = -1; if (infile != NULL) fd0 = open(infile, O_RDONLY); if (outfile != NULL) fd1 = open(outfile, O_CREAT | O_WRONLY, 0666); if(fd0 != -1) dup2(fd0, 0); if(fd1 != -1) dup2(fd1, 1); close(fd0); close(fd1); execvp(cmd, argv); fprintf(stderr, * Bad commandn);

38、 exit(1); wait(&sv); 第7章 第43頁(yè)管道操作管道操作(1)n 創(chuàng)建管道創(chuàng)建管道 int pipe(int pfd2)u創(chuàng)建一個(gè)管道,pfd0和pfd1分別為管道兩端的文件描述字,pfd0用于讀,pfd1用于寫(xiě)n 管道寫(xiě)管道寫(xiě)ret = write(pfd1, buf, n)u若管道已滿,則被阻塞,直到管道另一端read將已進(jìn)入管道的數(shù)據(jù)取走為止u管道容量:某一有限值,如8192字節(jié)第7章 第44頁(yè)管道操作管道操作(2)n 管道讀管道讀ret = read(pfd0, buf, n)u若管道寫(xiě)端已關(guān)閉,則返回0u若管道為空,且寫(xiě)端文件描述字未關(guān)閉,則被阻塞u若管道不為空(設(shè)

39、管道中實(shí)際有m個(gè)字節(jié))nm,則讀m個(gè);如果nm則讀取n個(gè)u實(shí)際讀取的數(shù)目作為read的返回值。u注意:管道是無(wú)記錄邊界的字節(jié)流通信n 關(guān)閉管道關(guān)閉管道closeu關(guān)閉寫(xiě)端則讀端read調(diào)用返回0。u關(guān)閉讀端則寫(xiě)端write導(dǎo)致進(jìn)程收到SIGPIPE信號(hào)(默認(rèn)處理是終止進(jìn)程,該信號(hào)可以被捕捉)寫(xiě)端write調(diào)用返回-1,errno被設(shè)為EPIPE第7章 第45頁(yè)父子進(jìn)程管道通信父子進(jìn)程管道通信n 父進(jìn)程父進(jìn)程pfd0pfd1pfd0pfd1pfd0pfd1pfd0pfd1pfd0pfd1n fork后后n 父進(jìn)程關(guān)閉讀端,父進(jìn)程關(guān)閉讀端,子進(jìn)程關(guān)閉寫(xiě)端子進(jìn)程關(guān)閉寫(xiě)端第7章 第46頁(yè)管道通信:寫(xiě)端

40、管道通信:寫(xiě)端/* File name : pwrite.c */#define syserr(str) perror(str); exit(1); main() int pfd2; char fdstr10, *message = Send/Receive data using pipe; if (pipe(pfd) = -1) syserr(Create pipe); switch(fork() case -1: syserr(fork); case 0: /* child */ close(pfd1); sprintf(fdstr, %d, pfd0); execlp(./pread,

41、pread, fdstr, 0); syserr(Execute pread file); break; default: /* parent */ close(pfd0); if(write(pfd1, message, strlen(message) + 1) = -1) perror(Write pipe); break; 第7章 第47頁(yè)管道通信:讀端管道通信:讀端/* File name : pread.c */#define syserr(str) perror(str); exit(1); main(int argc, char *argv) int fd, nbyte, i;

42、char buf1024; fd = strtol(argv1, 0, 0); nbyte = read(fd, buf, sizeof(buf); switch (nbyte) case -1: syserr(Read pipe); break; case 0: printf(Pipe closedn); break; default: printf(%d bytes %sn, nbyte, buf); break; exit(0);第7章 第48頁(yè)管道通信:應(yīng)注意的問(wèn)題管道通信:應(yīng)注意的問(wèn)題n 管道傳輸是一個(gè)無(wú)記錄邊界的字節(jié)流管道傳輸是一個(gè)無(wú)記錄邊界的字節(jié)流u寫(xiě)端一次write所發(fā)數(shù)據(jù)讀端

43、可能需多次read才能讀取u寫(xiě)端多次write所發(fā)數(shù)據(jù)讀端可能一次read就全部讀出n 父子進(jìn)程需要雙向通信時(shí),應(yīng)采用兩個(gè)管道父子進(jìn)程需要雙向通信時(shí),應(yīng)采用兩個(gè)管道u用一個(gè)管道,進(jìn)程可能會(huì)收到自己剛寫(xiě)到管道去的數(shù)據(jù)u增加其他同步方式太復(fù)雜n 父子進(jìn)程使用兩個(gè)管道傳遞數(shù)據(jù),有可能死鎖父子進(jìn)程使用兩個(gè)管道傳遞數(shù)據(jù),有可能死鎖u父進(jìn)程因輸出管道滿而寫(xiě),導(dǎo)致被阻塞u子進(jìn)程因要向父進(jìn)程寫(xiě)回足夠多的數(shù)據(jù)而導(dǎo)致寫(xiě)也被阻塞,這時(shí)死鎖發(fā)生u多進(jìn)程通信問(wèn)題必須仔細(xì)分析流量控制和死鎖問(wèn)題n 管道的缺點(diǎn):沒(méi)有記錄邊界管道的缺點(diǎn):沒(méi)有記錄邊界第7章 第49頁(yè)命名管道命名管道n pipe創(chuàng)建的管道的缺點(diǎn)創(chuàng)建的管道的缺點(diǎn)只

44、限于同祖先進(jìn)程間通信n 命名管道命名管道允許不相干的進(jìn)程(沒(méi)有共同的祖先)訪問(wèn)FIFO管道n 命名管道的創(chuàng)建命名管道的創(chuàng)建u用命令 mknod pipe0 pu創(chuàng)建一個(gè)文件,名字為pipe0u用ls -1列出時(shí),文件類型為pn 發(fā)送者發(fā)送者fd = open(”pipe0”, O_WRONLY);write(fd, buf, len);n 接收者接收者fd = open(”pipe0”, O_RDONLY);read(fd, buf, sizeof(buf);第7章 第50頁(yè)xsh2:管道管道(1)main() char buf256, *buf2, *cmd, *cmd2, *argv64,

45、 *argv264; int n, sv, fd2; for (;) printf(= ); if (fgets(buf, sizeof(buf), stdin) = NULL) exit(0); buf2 = strstr(buf, |); if (!buf2) exit(0); *buf2+ = 0; cmd = strtok(buf, tn); if (!cmd) exit(1); n = 0; argvn+ = cmd; while (argvn+ = strtok(NULL, tn); cmd2 = strtok(buf2, tn); if (!cmd2) exit(1); n =

46、0; argv2n+ = cmd2; while (argv2n+ = strtok(NULL, tn);第7章 第51頁(yè)xsh2:管道管道(2) pipe(fd); if (fork() = 0) dup2(fd0, 0); close(fd0); close(fd1); execvp(cmd2, argv2); fprintf(stderr, * bad commandn); exit(1); else if (fork() = 0) dup2(fd1, 1); close(fd0); close(fd1); execvp(cmd, argv); fprintf(stderr, * bad

47、 commandn); exit(1); close(fd0); close(fd1); wait(&sv); wait(&sv); 第7章 第52頁(yè)第二次上機(jī)作業(yè)第二次上機(jī)作業(yè)使用使用fork(), exec(), dup2(), pipe() ,open()系統(tǒng)調(diào)系統(tǒng)調(diào)用完成與下列用完成與下列shell命令等價(jià)的功能。命令等價(jià)的功能。grep v usr result.txt第7章 第53頁(yè)7.3 信號(hào)信號(hào)第7章 第54頁(yè)命令命令killn 用法與功能用法與功能kill signal PID-listkill命令用于向進(jìn)程發(fā)送一個(gè)信號(hào)n 舉例舉例ukill 1275向進(jìn)程1275的進(jìn)程發(fā)送

48、信號(hào),默認(rèn)信號(hào)為15(SIGTERM),一般會(huì)導(dǎo)致進(jìn)程死亡ukill -9 1326向進(jìn)程1326發(fā)送信號(hào)9(SIGKILL),導(dǎo)致進(jìn)程死亡第7章 第55頁(yè)進(jìn)程組進(jìn)程組n 進(jìn)程組進(jìn)程組u進(jìn)程在其proc結(jié)構(gòu)中有p_pgrp域up_pgrp都相同的進(jìn)程構(gòu)成一個(gè)“進(jìn)程組”u如果p_pgrp=p_pid則該進(jìn)程是組長(zhǎng)usetsid()系統(tǒng)調(diào)用將proc中的p_pgrp改為進(jìn)程自己的PID,從而脫離原進(jìn)程組,成為新進(jìn)程組的組長(zhǎng) ufork創(chuàng)建的進(jìn)程繼承父進(jìn)程p_pgrp,與父進(jìn)程同組n 舉例舉例ukill命令的PID為0時(shí),向與本進(jìn)程同組的所有進(jìn)程發(fā)送信號(hào)第7章 第56頁(yè)信號(hào)機(jī)制信號(hào)機(jī)制n 功能功能u

49、信號(hào)是送到進(jìn)程的“軟件中斷”,通知進(jìn)程出現(xiàn)了非正常事件n 信號(hào)的產(chǎn)生信號(hào)的產(chǎn)生u進(jìn)程自己或者其他進(jìn)程發(fā)出的使用kill()或者alarm()調(diào)用u核心產(chǎn)生信號(hào)段違例信號(hào)SIGSEGV:當(dāng)進(jìn)程試圖存取它的地址空間以外的存貯單元時(shí),內(nèi)核向進(jìn)程發(fā)送段違例信號(hào)浮點(diǎn)溢出信號(hào)SIGFPE:零做除數(shù)時(shí),內(nèi)核向進(jìn)程發(fā)送浮點(diǎn)溢出信號(hào)信號(hào)SIGPIPE:關(guān)閉管道讀端則寫(xiě)端write導(dǎo)致進(jìn)程收到信號(hào)SIGPIPE第7章 第57頁(yè)信號(hào)類型信號(hào)類型n 在在文件中定義宏文件中定義宏SIGTERM 軟件終止信號(hào)。用kill命令時(shí)產(chǎn)生SIGHUP 掛斷。當(dāng)從注冊(cè)shell中l(wèi)ogout時(shí), 同一進(jìn)程組的所有進(jìn)程都收到SIGH

50、UPSIGINT 中斷。用戶按Del鍵或Ctrl-C鍵時(shí)產(chǎn)生SIGQUIT 退出。按Ctrl-時(shí)產(chǎn)生,產(chǎn)生core文件SIGALRM 鬧鐘信號(hào)。計(jì)時(shí)器時(shí)間到,與alarm()有關(guān)SIGCLD 進(jìn)程的一個(gè)子進(jìn)程終止。SIGKILL 無(wú)條件終止,該信號(hào)不能被捕獲或忽略。SIGUSR1,SIGUSR2 用戶定義的信號(hào)SIGFPE 浮點(diǎn)溢出SIGILL 非法指令 SIGSEGV 段違例第7章 第58頁(yè)進(jìn)程對(duì)信號(hào)的處理進(jìn)程對(duì)信號(hào)的處理n 進(jìn)程對(duì)到達(dá)的信號(hào)可以在下列處理中選取一種進(jìn)程對(duì)到達(dá)的信號(hào)可以在下列處理中選取一種u信號(hào)被忽略u(píng)設(shè)置為缺省處理方式u信號(hào)被捕捉用戶在自己的程序中事先定義好一個(gè)函數(shù),當(dāng)信號(hào)

51、發(fā)生后就去執(zhí)行這一函數(shù)n 信號(hào)被設(shè)為缺省處理方式信號(hào)被設(shè)為缺省處理方式 signal(SIGINT,SIG_DFL);n 信號(hào)被忽略信號(hào)被忽略 signal(SIGINT,SIG_IGN);在執(zhí)行了這個(gè)調(diào)用后,進(jìn)程就不再收到SIGINT信號(hào)注意:被忽略了的信號(hào)作為進(jìn)程的一種屬性會(huì)被它的子進(jìn)程所繼承第7章 第59頁(yè)信號(hào)被忽略:舉例信號(hào)被忽略:舉例/* File name : abc.c */#include main() signal(SIGTERM, SIG_IGN); if (fork() for(;) sleep(100); else execlp(”xyz”, ”xyz”, 0);/*

52、File name : xyz.c */main() int i = 0; for (;) printf(”%dn”, i+); sleep(1); n 單獨(dú)運(yùn)行xyz時(shí),使用kill -15命令可殺死該進(jìn)程n 由abc進(jìn)程來(lái)啟動(dòng)的xyz進(jìn)程就不能用kill -15命令殺死第7章 第60頁(yè)信號(hào)的捕捉信號(hào)的捕捉n 信號(hào)被捕捉并由一個(gè)用戶函數(shù)來(lái)處理信號(hào)被捕捉并由一個(gè)用戶函數(shù)來(lái)處理n 信號(hào)到達(dá)時(shí),這個(gè)函數(shù)將被調(diào)用來(lái)處理那個(gè)信號(hào)信號(hào)到達(dá)時(shí),這個(gè)函數(shù)將被調(diào)用來(lái)處理那個(gè)信號(hào)#include sig_handle(int sig) printf(”HELLO! Signal %d catched.n”,si

53、g);main() signal(SIGINT, sig_handle); signal(SIGQUIT, sig_handle); for(;) sleep(500);n 注意:在信號(hào)的用戶函數(shù)被調(diào)用之前,自動(dòng)被重置到注意:在信號(hào)的用戶函數(shù)被調(diào)用之前,自動(dòng)被重置到它的缺省行為。它的缺省行為。第7章 第61頁(yè)僵尸進(jìn)程僵尸進(jìn)程n 僵尸子進(jìn)程僵尸子進(jìn)程u子進(jìn)程終止,僵尸進(jìn)程(defunct或zombie)出現(xiàn),父進(jìn)程使用wait系統(tǒng)調(diào)用收尸后消除僵尸n 僵尸進(jìn)程對(duì)資源的占用僵尸進(jìn)程對(duì)資源的占用u僵尸進(jìn)程不占用內(nèi)存資源等但占用內(nèi)核proc表項(xiàng),僵尸進(jìn)程太多會(huì)導(dǎo)致proc表耗盡而無(wú)法再創(chuàng)建新進(jìn)程n 子

54、進(jìn)程中止后的通知機(jī)制子進(jìn)程中止后的通知機(jī)制u子進(jìn)程中止后,系統(tǒng)會(huì)向父進(jìn)程發(fā)送信號(hào)SIGCLDn 不導(dǎo)致僵尸子進(jìn)程出現(xiàn)的方法不導(dǎo)致僵尸子進(jìn)程出現(xiàn)的方法u忽略對(duì)SIGCLD信號(hào)的處理 signal(SIGCLD,SIG_IGN);u捕獲SIGCLD信號(hào),執(zhí)行wait系統(tǒng)調(diào)用第7章 第62頁(yè)捕獲信號(hào)捕獲信號(hào)SIGCLDSIGCLDint subprocess_die(int sig) int pid, status; pid = wait(&status); . . . signal(SIGCLD, subprocess_die); int main() signal(SIGCLD, subproc

55、ess_die); . . .第7章 第63頁(yè)發(fā)送信號(hào)發(fā)送信號(hào)n 系統(tǒng)調(diào)用系統(tǒng)調(diào)用kill int kill(int pid, int sig) 返回值: 0-成功 -1-失敗n kill調(diào)用分幾種情況調(diào)用分幾種情況u當(dāng)pid0時(shí),向指定的進(jìn)程發(fā)信號(hào)u當(dāng)pid=0時(shí),向與本進(jìn)程同組的所有進(jìn)程發(fā)信號(hào)u當(dāng)pid0時(shí),將時(shí)鐘設(shè)置成secs指定的秒數(shù)當(dāng)secs=0時(shí),關(guān)閉報(bào)警時(shí)鐘。第7章 第66頁(yè)alarm系統(tǒng)調(diào)用舉例系統(tǒng)調(diào)用舉例#include char cmd100;default_cmd(int sig) printf(CMD_An); strcpy(cmd, CMD_A);main() sig

56、nal(SIGALRM, default_cmd); alarm(5); printf(Input command : ); scanf(%s, cmd); alarm(0); printf(cmd=%sn, cmd); . .第7章 第67頁(yè)全局跳轉(zhuǎn)全局跳轉(zhuǎn)(1)main() int c; for (;) printf(”Input a command:”); c = getchar(); switch(c) case Q: return(0); break; case A: func_a(); break; case B: func_b(); break; . . . n 問(wèn)題問(wèn)題u用戶在

57、輸入了命令A(yù)后反悔,希望中止func_a()對(duì)命令A(yù)的處理,而要重新選擇另一條命令第7章 第68頁(yè)全局跳轉(zhuǎn)全局跳轉(zhuǎn)(2)#include void main_control(int sig) int c; signal(SIGINT, main_control); for (;) printf(”Input your choice:”); scanf(”%d”, &c); switch (c) case 0: return; break; case 1: func_1(); break; case 2: func_2(); break; . . main() main_control();第7

58、章 第69頁(yè)全局跳轉(zhuǎn)全局跳轉(zhuǎn)(3)n 上述程序存在的問(wèn)題上述程序存在的問(wèn)題u每次按下中斷鍵,程序停留在信號(hào)捕捉函數(shù)中,堆棧沒(méi)有清理,嵌套越來(lái)越深浪費(fèi)越來(lái)越大umain_control()一旦返回,進(jìn)程的執(zhí)行將彈回到剛才被SIGINT中斷的地方恢復(fù)剛才的執(zhí)行會(huì)讓用戶感到迷惑不解,剛才的動(dòng)作已打斷而且又已經(jīng)開(kāi)始了新的工作,可過(guò)一段時(shí)間后又開(kāi)始運(yùn)行uC語(yǔ)言中的goto語(yǔ)句只限于一個(gè)函數(shù)體內(nèi)使用,不能解決上述的問(wèn)題第7章 第70頁(yè)全局跳轉(zhuǎn)全局跳轉(zhuǎn)(4)n 解決方法解決方法u把?;謴?fù)為第一次調(diào)用main_control()時(shí)的狀態(tài),再調(diào)用main_control()去重新執(zhí)行n 有兩個(gè)標(biāo)準(zhǔn)的子例程用于這

59、個(gè)目的有兩個(gè)標(biāo)準(zhǔn)的子例程用于這個(gè)目的#include int setjmp(jmp_buf jmpenv); /* 返回值為零,或者是longjmp提供的val */void longjmp(jmp_buf jmpenv, int val) /* val是提供給setjmp作返回值*/第7章 第71頁(yè)全局跳轉(zhuǎn)全局跳轉(zhuǎn)(5)#include #include static jmp_buf jmpbuf;void intr_proc(int sig) printf(”n.INTERRUPTED by signal %dn”, sig) longjmp(jmpbuf, 1);main() int c

60、; setjmp(jmpbuf); signal(SIGINT, intr_proc); for(;) printf(”Input a command:”); scanf(“%d”, &c); switch(c) case 0: return; break; case 1: func_1(); break; case 2: func_2(); break; 第7章 第72頁(yè)7.4 消息隊(duì)列消息隊(duì)列第7章 第73頁(yè)消息隊(duì)列的創(chuàng)建消息隊(duì)列的創(chuàng)建n 系統(tǒng)調(diào)用系統(tǒng)調(diào)用msgget #include #include #include int msgget(key_t key, int flags);u

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論