嵌入式LINUX_C基礎(chǔ)09_第1頁
嵌入式LINUX_C基礎(chǔ)09_第2頁
嵌入式LINUX_C基礎(chǔ)09_第3頁
嵌入式LINUX_C基礎(chǔ)09_第4頁
嵌入式LINUX_C基礎(chǔ)09_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、ESD_DAY031_ElvisUNIX/LINUX 系統(tǒng)下的C高級編程A.N.E.K1.目錄的管理1.1 使用opendir函數(shù)打開目錄使用時引入頭文件sys/stat.h,dirent.h功能:打開參數(shù)指定的目錄。格式:DIR* opendir(const char*name);注意:一個參數(shù):想打開的目錄路徑,雙引號括起來;多級路徑可能需要sprintf函數(shù)拼接。返回值:成功返回目錄指針,失敗返回NULL。1.2 使用readdir函數(shù)讀取目錄使用時引入頭文件dirent.h功能:讀取參數(shù)指定目錄中的內(nèi)容。格式:struct dirent* readdir(DIR*dirp);注意:一個

2、參數(shù):目錄指針,函數(shù)opendir()的返回值;返回值:成功返回結(jié)構(gòu)體指針,失敗返回NULL。struct dirent . . . unsigned char d_type; /文件的類型 char d_name256;/文件的名稱. . . ;1.3 使用closedir函數(shù)關(guān)閉目錄使用時引入頭文件dirent.h功能:關(guān)閉參數(shù)指定的目錄。格式:int closedir(DIR*dirp);注意:一個參數(shù):目錄指針,函數(shù)opendir()的返回值;返回值:成功返回0,失敗返回-1。*目錄的基本操作*#include<stdio.h>#include<stdlib.h>

3、;#include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<dirent.h>int main() /1.打開目錄 DIR*dir=opendir("./day09"); if(NULL=dir) perror("opendir"); exit(-1); printf("打開目錄成功n"); /2.遍歷目錄中的內(nèi)容 struct dirent*ent;/=readdir(dir); /while(NULL!=e

4、nt) while(ent=readdir(dir) /打印讀取到的類型和文件名 /4->目錄,8->文件 printf("%d,%sn",ent->d_type,ent->d_name); /讀取下一個 /ent=readdir(dir); /3.關(guān)閉目錄 int res=closedir(dir); if(-1=res) perror("closedir"); exit(-1); printf("成功關(guān)閉目錄n"); return 0;*練習:編程實現(xiàn)打印指定目錄中的所有內(nèi)容,要求子目錄中的內(nèi)容也要打印出來

5、*#include<stdio.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<dirent.h>#include<string.h>void print(char*path);int main() print("./day02"); return 0;void print(char*path) /1.打開目錄 DIR*dir=opendir(path); if(NULL=dir) perror("op

6、endir"); return; printf("目錄打開成功n"); /2循環(huán)讀取目錄中的內(nèi)容 struct dirent*ent; while(ent=readdir(dir) /2.1如果讀取到目錄,則打印再遞歸 if(4=ent->d_type) printf("%sn",ent->d_name); /特殊處理特殊目錄.和. if(!strcmp(ent->d_name,".")|!strcmp(ent->d_name,".") continue; /拼接新的路徑 char

7、 buf100=0; sprintf(buf,"%s/%s",path,ent->d_name); /調(diào)用遞歸子目錄中的內(nèi)容 print(buf); /2.2如果讀取到文件,則直接打印 if(8=ent->d_type) printf("%sn",ent->d_name); int res=closedir(dir); if(-1=res) perror("closedir"); exit(-1); printf("成功關(guān)閉文件n");1.4 其他相關(guān)的函數(shù)mkdir()-創(chuàng)建一個目錄rmdir(

8、)-刪除一個目錄chdir()-改變目錄getcwd()-獲取當前進程所在目錄,get current working directory。2.進程管理2.1 基本概念和基本命令(1)基本概念程序就是存放在磁盤上的一個可執(zhí)行文件,進程就是指運行在內(nèi)存中的程序。同一個程序可以啟動多個進程。(2)基本命令ps-查看當前終端中啟動的進程(進程的快照)。ps命令的執(zhí)行結(jié)果:PID-進程號;TTY-終端的次要裝置號碼(了解);TIME-命令占用CPU的時間(了解);CMD-命令的名稱;ps -aux-表示顯示所有包含其他使用者的進程;ps -aux|more-分屏顯示所有的進程;”|”表示管道,即ps-

9、aux命令的結(jié)果通過一個管道存放到more中;進程的狀態(tài):S:休眠狀態(tài),以減輕CPU的壓力;s:進程的領(lǐng)導(dǎo)者,旗下有子進程;Z:僵尸進程,已經(jīng)結(jié)束的進程,但是資源沒有回收;R:正在運行的進程;O:可以運行的進程,T:掛起狀態(tài)的進程,現(xiàn)場保護;<:優(yōu)先級較高的進程;N;優(yōu)先級較低的進程ps -ef-表示以全格式的方式顯示進程的信息;ps -ef|more-表示分屏顯示進程的信息UID-用戶的編號;PID-進程的編號;PPID-父進程的編號;C-占用的CPU百分比;STIME-進程的開始時間;TTY-終端號;TIME-消耗CPU的時間;CMD-進程的名稱如果進程A啟動了進程B,那么進程A就叫

10、做進程B的父進程,進程B叫做進程A的子進程,目前主流的操作系統(tǒng)都是支持多進程的。系統(tǒng)中進程0是系統(tǒng)的內(nèi)部的進程,負責啟動進程1(init)和進程2,其他所有進程都是直接/簡介由進程1和進程2啟動起來的,從而形成了一個樹形結(jié)構(gòu)。kill -9-表示殺死指定的進程2.2 各種ID的獲取PID-進程的編號,系統(tǒng)采用進程的編號來唯一標識一個進程,采用延遲重用的策略進行管理,在任意時刻都保證進程號是唯一的。getpid()-獲取當前進程的進程號;getppid()-獲取當前進程的父進程的進程號;getuid()-獲取用戶的編號;getgid()-獲取用戶組的編號;其中進程號的數(shù)據(jù)類型是pid_t,本質(zhì)是

11、int類型,但是一般都是從0開始使用;用戶ID的數(shù)據(jù)類型是uid_t,本質(zhì)上是unsigned int型;用戶組ID的數(shù)據(jù)類型是gid_t,本質(zhì)上是unsigned int類型。2.3 進程的創(chuàng)建(1)fork函數(shù)使用時引入頭文件unistd.h功能:以復(fù)制正在調(diào)用進程的方式來創(chuàng)建新進程,其中正在調(diào)用的進程叫做父進程,創(chuàng)建出來的新進程叫做子進程。格式:pid_t fork();注意:無參數(shù);返回值:成功調(diào)用時在父進程中返回子進程的進程號,子進程返回0,失敗調(diào)用失敗時父進程返回-1,子進程沒有被創(chuàng)建出來。/使用fork函數(shù)創(chuàng)建子進程#include<stdio.h>#include&

12、lt;stdlib.h>#include<unistd.h>#include<sys/types.h>int main() printf("main函數(shù)開始執(zhí)行n");/執(zhí)行一次 /使用fork函數(shù)創(chuàng)建子進程 pid_t pid=fork(); if(-1=pid) perror("fork"); exit(-1); /printf("main函數(shù)結(jié)束n,%d",pid);/執(zhí)行兩次 /分辨子進程 if(0=pid) printf("我是子進程,我的進程號是:%d,我的父進程是:%dn"

13、;,getpid(),getppid(); sleep(3); printf("我是子進程,我的進程號是:%d,我的父進程是:%dn",getpid(),getppid();/此時,這里的父進程已經(jīng)是init,其進程號是1 else sleep(1); printf("我是父進程,我的進程號是%d,我的子進程號是:%dn",getpid(),pid); return 0;(2)使用fork函數(shù)創(chuàng)建的子進程的執(zhí)行方式a.對于fork函數(shù)之前的代碼,父進程執(zhí)行一次;b.對于fork函數(shù)之后的代碼,父子進程各執(zhí)行一次;連同fork()函數(shù)的一部分也再執(zhí)行1次,

14、因此會有兩個返回值。c.對于fork函數(shù)的返回值來說,父子進程各返回一次,父進程返回子進程的ID,子進程返回0;因此可以通過函數(shù)的返回值來區(qū)分父子進程。(3)父子進程之間的關(guān)系a.父進程啟動子進程,父子進程同時工作,如果子進程結(jié)束,則會給父進程發(fā)信號SIGCHLD,由父進程幫助其回收資源;b.如果父進程先結(jié)束,則子進程會變成孤兒進程,子進程會變更父進程(重新設(shè)定父進程,init(1)進程),init進程叫做孤兒院;c.如果子進程先結(jié)束,但是父進程由于各種原因沒有收到子進程發(fā)來的信號,也就沒有幫助子進程回收資源,則子進程就會變成僵尸進程;注意:使用fork函數(shù)創(chuàng)建子進程后,父子進程的執(zhí)行順序由操

15、作系統(tǒng)調(diào)度。(4)父子進程之間的內(nèi)存資源關(guān)系*觀察父子進程之間的內(nèi)存關(guān)系*#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<sys/types.h>int i1=1;/全局變量,全局區(qū)int main() int i2=1;/局部變量,棧區(qū) /pc指向堆區(qū),pc本身在棧區(qū) char*pc=(char*)malloc(sizeof(char)*10); strcpy(pc,"hello"); /使用fork函

16、數(shù)創(chuàng)建子進程 pid_t pid=fork(); if(-1=pid) perror("fork"); exit(-1); /子進程 if(0=pid) i1=2; i2=2; strcpy(pc,"HELLO"); printf("子進程中:i1=%d,i2=%d,pc=%sn",i1,i2,pc); exit(0);/終止子進程 sleep(1);/保證子進程先結(jié)束 printf("父進程中:i1=%d,i2=%d,pc=%sn",i1,i2,pc); return 0;/父子進程打印的結(jié)果不一樣,說明實際內(nèi)存

17、并沒有共享可見,對于fork函數(shù)創(chuàng)建的子進程來說,復(fù)制父進程中除了代碼區(qū)之外的其他內(nèi)存區(qū)域,代碼區(qū)和父進程共享。(5)擴展a.如何創(chuàng)建3個進程,一共4個進程:連續(xù)調(diào)用兩次fork函數(shù),4個進程:1個父進程+2個子進程+1個孫進程。以指數(shù)級增長。b.如何創(chuàng)建2個子進程,一共3個進程:pid=fork();if(pid!=0) fork();/在父進程中單獨調(diào)用,1個進程+2個子進程;c.俗稱:fork炸彈while(1) fork();2.4 進程的終止(1)進程的正常終止方式a.在main函數(shù)中執(zhí)行了return 0表示正常結(jié)束;b.調(diào)用exit(0)函數(shù);c.調(diào)用_exit(0)/_Exit

18、(0)函數(shù)來終止進程d.最后一個線程返回;e.最后一個線程調(diào)用了pthread_exit函數(shù)(2)進程的異常終止方式a.采用信號來終止進程;b.最后一個線程被其他線程調(diào)用pthread_cancle取消(3)相關(guān)函數(shù)的解析_exit()/_Exit()函數(shù):功能:立即終止當前正在運行的進程。格式:#include <unistd.h> void _exit(int status); #include <stdlib.h> void _Exit(int status);注意:_exit()和_Exit()函數(shù)功能上完全相同;在終止進程時,會自動關(guān)閉屬于該進程的文件描述符,

19、會給該進程的父進程發(fā)送SIGCHLD信號,該進程的所有子進程會重新認定新的父進程為init;參數(shù)值會被返回給父進程作為該進程終止時的退出狀態(tài)信息,父進程需要調(diào)用wait系列函數(shù)來獲取該數(shù)據(jù)。返回值:無返回值exit()函數(shù):功能:引起正常進程的終止。格式:#include <stdlib.h> void exit(int status);注意:將參數(shù)status&0377之后的數(shù)據(jù)返回給當前進程的父進程 自動調(diào)用所有被atexit()和on_exit()函數(shù)注冊過的函數(shù),一般用于處理善后工作。返回值:無返回值atexit()函數(shù):功能:對參數(shù)指定的函數(shù)進程注冊。格式:#in

20、clude <stdlib.h> int atexit(void(*function)(void);注意:所有被該函數(shù)注冊過的函數(shù)會在正常終止時被調(diào)用,而正常進程終止的主要方式為:調(diào)用exit函數(shù)和執(zhí)行main函數(shù)中的return。返回值:成功返回0,失敗返回非零。*使用不同的函數(shù)終止進程*#include<stdio.h>#include<stdlib.h>#include<unistd.h>void show(void)/當執(zhí)行到return時調(diào)用此函數(shù) printf("Komachi wa tsuyoin");int main() /調(diào)用atexit函數(shù)進行注冊,但不會調(diào)用函數(shù) int res=atexit(show);/注冊show函數(shù) if(0

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論