本文幫你在 Unix 下玩轉(zhuǎn) C 語言

  • shell是一種特殊的應(yīng)用程序(命令行解釋器)街望,他為運行其他應(yīng)用程序提供了一個接口嘴拢。

  • posix規(guī)范了操作系統(tǒng)是什么樣

  • 每個進(jìn)程都有一個工作目錄(又叫當(dāng)前目錄)仗处,相對路徑都是從工作目錄開始解釋优幸。

  • Ctrl+D是文件結(jié)束字符

  • read讀指定字節(jié)數(shù)吨拍;fgets是讀取一行

  • 三個進(jìn)程控制函數(shù):fork exec waitpid。 waitpid【此函數(shù)獲取信息网杆,釋放資源】父進(jìn)程等待子進(jìn)程終止羹饰,可以得到子進(jìn)程何時終止。system函數(shù)是在exec外包了一層碳却。

  • execlp要求參數(shù)以null結(jié)束队秩,換行符不可以

  • 線程id只在它所屬進(jìn)程內(nèi)起作用,在另一個進(jìn)程中無意義昼浦,可以使用線程id引用相應(yīng)的線程馍资。

  • 一個用戶可以屬于多至16個組

  • ctrl+c中斷鍵,ctrl+\退出鍵关噪,等價于kill函數(shù)鸟蟹。kill(pid, SIGTERM)向另一進(jìn)程發(fā)信號,發(fā)起信號的必須是該進(jìn)程的所有者使兔。

  • (gdb)set follow-fork-mode child使gdb進(jìn)入子進(jìn)程建钥,事實證明不設(shè)置(默認(rèn)調(diào)試父進(jìn)程)這句無法進(jìn)入pid==0的語句塊。子進(jìn)程exit后無法再設(shè)置斷點gdb信息丟失火诸,此時run可能啟動的不是父進(jìn)程而是孫進(jìn)程锦针。

  • fork會復(fù)制fork開始直到函數(shù)結(jié)束的代碼【共享代碼正文,但復(fù)制全部變量】

  • 日歷時間:1970至今秒數(shù)置蜀,time_t類型用于保存這種時間奈搜。

  • 進(jìn)程時間:cpu時間,clock_t類型用于保存這種時間盯荤。

  • 系統(tǒng)cpu時間是進(jìn)程執(zhí)行內(nèi)核程序的時間馋吗。執(zhí)行用戶指令的時間是用戶cpu時間。兩者之和是cpu時間秋秤。時鐘時間【墻上鐘時間】宏粤,是進(jìn)程運行的時間總量脚翘,和進(jìn)程數(shù)有關(guān)。time ls【ls可換成任意程序名】 查看時間绍哎。

  • clock_t times(struct tms* buf)成功返回墻上鐘時間【必須使用相對值来农,做差】

  • 庫函數(shù)不一定調(diào)用系統(tǒng)調(diào)用。應(yīng)用程序可以直接調(diào)用系統(tǒng)調(diào)用崇堰,也可以通過C庫函數(shù)調(diào)用系統(tǒng)調(diào)用沃于。

  • ISO C標(biāo)準(zhǔn)有24個頭文件(包括stdlib.h,stdio.h)。

  • 接口即協(xié)議海诲。

  • 很多程序需要為路徑分配存儲區(qū)

  • 守護(hù)進(jìn)程:后臺運行且不與終端相連接的一種進(jìn)程繁莹。

  • 與文件或目錄無關(guān)的選項用sysconf確定,與文件或目錄有關(guān)的選項用pathconf,fpathconf確定特幔。

  • unix系統(tǒng)的大多數(shù)文件I/O只需要用到5個函數(shù):open close read write lseek咨演,都是不帶緩沖的I/O。不帶緩沖指的是read write都調(diào)用內(nèi)核的一個系統(tǒng)調(diào)用蚯斯。不帶緩沖的io不是iso c的組成部分薄风,是posix的組成部分。

  • 對內(nèi)核而言溉跃,所有的打開的文件都通過文件描述符(非負(fù)整數(shù))引用村刨。0 1 2 分別是輸入 輸出 錯誤 的描述符。文件描述符變化范圍0-OPEN_MAX(表示每個進(jìn)程可以打開OPEN_MAX個文件)撰茎。

  • open函數(shù):int fileId【返回最小的未用文件描述符數(shù)值】 = open(tmpPtr->_fileName【文件名】,O_RDWR【讀嵌牺、寫打開】|O_CREAT【如果不存在則創(chuàng)建】, 0666【配合O_CREATE指定新文件訪問權(quán)限】);

  • close(fileId);關(guān)閉文件同時釋放進(jìn)程加在該文件上的所有記錄鎖。進(jìn)程終止時內(nèi)核自動關(guān)閉它打開的文件龄糊。

  • 返回文件偏移量【偏移量始終存在逆粹,讀稍浆、寫操作從它指向的位置開始】=lseek(fileId,offset【每一個打開的文件都有一個當(dāng)前文件偏移量重父,默認(rèn)0,除非指定O_APPEND】,SEEK_SET【將偏移量設(shè)為文件開始處offset字節(jié)】)

  • lseek返回-1說明文件描述符對應(yīng)的文件是管道并炮、fifo或網(wǎng)絡(luò)套接字他嚷。某些設(shè)備允許負(fù)的偏移量蹋绽。

  • od -c 文件名 【-c表示以字符方式打印文件內(nèi)容】 ls -ls 查看文件占用多少個磁盤塊

  • nRead【返回讀到字節(jié)數(shù)】 = read(flag_fd【文件描述符】, buffer【讀取數(shù)據(jù)到buffer中】, length【一次讀取字節(jié)數(shù)】) 【成功返回前,偏移量增加讀到的字節(jié)數(shù)】

  • int bytes_write【返回寫入字節(jié)數(shù)】 = write(fileHandle,ptr,writeSize【寫入字節(jié)數(shù)】) 【寫操作從當(dāng)前偏移量開始筋蓖,成功后偏移量自動增加寫入字節(jié)數(shù)】

  • 測量文件讀寫由于緩存機(jī)制卸耘,在第一次之后可能不準(zhǔn)確。

  • 每個進(jìn)程都有一張打開文件描述符表->文件表(當(dāng)前文件偏移量)->v節(jié)點信息

  • 可能有多個文件描述符指向同一文件表項粘咖,多個文件表項指向一個v節(jié)點表蚣抗。多進(jìn)程讀同一個文件沒有問題,但是寫同一個文件會有問題->原子操作瓮下。

  • open中用O_CREAT和O_EXCL可以將測試和創(chuàng)建合并為一個原子操作翰铡。原子操作指多步組成的操作要么執(zhí)行完所有步驟钝域,要么一步也不執(zhí)行。

  • 先lseek再write不可能是原子操作锭魔。兩個函數(shù)間內(nèi)核可以掛起進(jìn)程例证。

  • pread(..., off_t offset) pwrite(..., off_t offset) 相當(dāng)于順序調(diào)用lseek和read,與順序調(diào)用的區(qū)別:無法中斷赂毯、不更新文件指針

  • O_APPEND方式打開文件战虏,每次write,文件偏移量自動定位到文件尾党涕。

  • 新的文件描述符 = dup(int filedes) dup2(int filedes【被復(fù)制】,int filedes2【指定數(shù)值】) 復(fù)制現(xiàn)存的文件描述符,與參數(shù)filedes共享同一個文件表項巡社。fcntl(..)也可以復(fù)制文件描述符膛堤。

  • sync將塊緩沖區(qū)排入寫隊列,不等實際寫磁盤晌该。fsync對單一文件起作用肥荔,等寫磁盤結(jié)束返回,更新屬性朝群。fdatasync只影響文件的數(shù)據(jù)部分燕耿。

  • fcntl(..)返回值和命令有關(guān),可以返回文件狀態(tài)姜胖,文件描述符誉帅。可以修改文件狀態(tài)右莱。

  • 5<>temp表示在文件描述符5上打開文件供讀寫蚜锨。

  • 終端I/O是 ioctl的最大使用方面。

  • digit1 > &digit2表示要將digit1重定向至描述符2的同一個文件慢蜓。

  • shell從左到右處理命令

  • struct stat sA【stat結(jié)構(gòu)體包含磁盤號亚再,所有者,訪問修改時間等屬性】; int retA【返回小于0表示文件不存在】 = stat(fileNameA.c_str(),&sA【stat函數(shù)將填寫sA】); ls -l就是使用的stat(...)函數(shù)

  • lstat(...)的增強(qiáng)功能是檢測符號鏈接

  • 文件類型信息包含在stat結(jié)構(gòu)的st_mode成員中晨抡,有下面幾種類型氛悬。
    普通文件【包含某種數(shù)據(jù)的文件,數(shù)據(jù)是文本還是二進(jìn)制對內(nèi)核而言無區(qū)別耘柱,對文件內(nèi)容的解釋由處理該文件的應(yīng)用程序進(jìn)行如捅。例外:二進(jìn)制可執(zhí)行文件遵守內(nèi)核理解的統(tǒng)一格式】
    目錄文件【包含其他文件的名字以及指向與這些文件有關(guān)信息的指針】
    塊設(shè)備文件【磁盤,提供對設(shè)備帶緩沖的訪問】
    字符設(shè)備文件【鍵盤帆谍,提供對設(shè)備不帶緩沖的訪問】
    FIFO 又名管道文件伪朽,shell里的豎線 | 【用于進(jìn)程間通信】
    套接字【這種文件用于進(jìn)程間的網(wǎng)絡(luò)通信,也可用于一臺機(jī)上進(jìn)程間的非網(wǎng)絡(luò)通信】
    符號鏈接【這種文件類型指向另一個文件】

  • 進(jìn)程間通信(IPC)對象也表示為文件:消息隊列汛蝙、信號量烈涮、共享存儲對象朴肺。

  • 執(zhí)行一個程序時exec(...)會保存有效用戶ID和有效組ID。通常有效ID==實際ID坚洽。

  • 當(dāng)文件的有效用戶ID設(shè)置為文件所有者ID時戈稿,如果所有者為root,即使被一個普通用戶執(zhí)行讶舰,該進(jìn)程也具有超級權(quán)限鞍盗。

  • 文件訪問權(quán)限:第一個規(guī)則是我們用名字打開一個文件時,對該名字包含的每一個目錄跳昼,包括她可能隱含的當(dāng)前工作目錄(./)都應(yīng)具有執(zhí)行權(quán)限般甲。對文件有適當(dāng)?shù)臋?quán)限,取決于以何種方式打開鹅颊。

  • 對目錄的讀權(quán)限使我們可以獲得該目錄所有文件名列表敷存。對目錄的執(zhí)行權(quán)限使我們可以通過該目錄,也就是【搜索】該目錄堪伍,尋找一個特定的文件名锚烦。

  • 創(chuàng)建文件需要對目錄有寫權(quán)限和可執(zhí)行權(quán)限。刪除文件需要對目錄有寫和可執(zhí)行權(quán)限【實際是減少文件i節(jié)點的一個連接數(shù)而已帝雇,文件本身還存在】涮俄,對文件本身不需要有讀、寫權(quán)限【刪除對文件本身沒讀沒寫】尸闸。

  • 新文件的用戶ID設(shè)置為進(jìn)程的有效用戶ID彻亲。新文件的組ID可以是:1.進(jìn)程的有效組ID。2.它所在目錄的組ID室叉。

  • access(pathname, mode)按實際用戶ID睹栖,和實際組ID進(jìn)行訪問權(quán)限測試。只有root能chown.

  • umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);設(shè)置進(jìn)程的文件模式創(chuàng)建屏蔽字
    creat("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH)
    先后運行上面兩行的運行結(jié)果-rw------- bar
    chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) fchmod(fildes, mod)
    運行結(jié)果-rw-r--r-- bar

  • -rw-rwSrw- S表示設(shè)置組ID【有效用戶ID和組ID】位已設(shè)置【有效用戶ID變成文件所有者的ID】茧痕,同時野来,組執(zhí)行位則未設(shè)置。

  • linux交換區(qū)==windows下虛擬內(nèi)存

  • chmod a+t 目錄 設(shè)置粘住位

  • 粘住位:可執(zhí)行程序正文副本保存在交換區(qū)踪旷。目錄設(shè)置了粘住位曼氛,只有對目錄有寫權(quán)限加上1.擁有文件;2.擁有目錄令野;3.root三種之一 才可以刪除或更名目錄下的文件舀患。

  • chown fchown lchown更改文件用戶ID

  • truncate(pathnane, length) ftruncate(filedes, length) 截斷文件或創(chuàng)建空洞

  • 磁盤可分為多個區(qū),不同的區(qū)有不同的文件系統(tǒng)气破。

  • 目錄項【目錄/文件名】->i節(jié)點->實際數(shù)據(jù)塊聊浅。多個目錄項可以指向同一個i節(jié)點,例如軟連接和目錄本身指向的是同一塊數(shù)據(jù),就應(yīng)該指向的是同一個i節(jié)點低匙。mv只更改目錄名旷痕,不移動實際數(shù)據(jù)。

  • link(existpath, newpath)創(chuàng)建一個新的目錄項顽冶,增加鏈接數(shù)欺抗;unlink(pathname)刪除目錄項,將pathname所引用的文件鏈接數(shù)減1. 目錄項刪除后看不見文件强重,但文件仍有可能占據(jù)磁盤空間直至被內(nèi)核刪除绞呈。

  • ./a.out & 表示后臺運行

  • 如果打開文件的進(jìn)程數(shù)和鏈接數(shù)同時為0,內(nèi)核會刪除該文件间景。

  • remove(pathname)解除對一個目錄或文件的鏈接佃声。rename(oldname, newname)

  • 普通目錄項和文件本身的關(guān)系是硬鏈接,她直接指向文件的i節(jié)點拱燃。符號鏈接是指向一個文件的間接指針秉溉,可以跨不同的文件系統(tǒng)。要注意函數(shù)是否跟隨符號鏈接碗誉。

  • symlink(actualpath, sympath)創(chuàng)建符號鏈接。readlink(pathname, buf, bufsize)打開鏈接本身父晶,并讀鏈接中的名字哮缺。

  • ls -lt默認(rèn)按文件修改時間排序,-u按訪問時間甲喝,-c按更改狀態(tài)時間尝苇。utime(pathname, times)更改文件的訪問和更改時間。

  • mkdir(pathname, mode)創(chuàng)建一個新的空目錄埠胖。rmdir(pathname)刪除一個空目錄糠溜。

  • DIR *opendir(pathname) struct dirent *readdir(DIR *dp) chdir(...)【當(dāng)前工作目錄是進(jìn)程的一個屬性,chdir只影響進(jìn)程本身】 fchdir(...) getcwd(...)獲得完整絕對路徑

  • 標(biāo)準(zhǔn)I/O庫【ISO C標(biāo)準(zhǔn)】文件操作圍繞文件描述符直撤,也可以理解成圍繞流(stream)非竿。當(dāng)用標(biāo)準(zhǔn)io打開或創(chuàng)建一個文件時,我們已使一個流與文件關(guān)聯(lián)谋竖。標(biāo)準(zhǔn)IO最終都要調(diào)用read,write红柱。

  • FILE結(jié)構(gòu)包含:文件描述符、緩沖區(qū)指針蓖乘、緩沖區(qū)長度锤悄、當(dāng)前緩沖區(qū)字節(jié)數(shù)以及出錯標(biāo)志。文件指針是FILE*

  • 標(biāo)準(zhǔn)輸入輸出的文件指針是stdin,stdout,stderr嘉抒。io庫提供緩沖的目的是減少使用read和write的調(diào)用次數(shù)零聚。標(biāo)準(zhǔn)io函數(shù)通常調(diào)用malloc獲得緩沖區(qū)。

  • setbuf(FILE* , buf, mode ,size)更改緩沖類型。 fflus(FILE *fp)此函數(shù)使該流所有未寫的數(shù)據(jù)都被傳送至內(nèi)核隶症。

  • FILE *fdopen(filedes, type)使已有的文件描述符和流關(guān)聯(lián)政模。

  • FILE *freopen(pathname, type, FILE *restrict fp)在一個指定的流上打開文件,若流已打開沿腰,先關(guān)閉流览徒。一般用于將指定文件打開為一個預(yù)定義的流:輸入,輸出颂龙,錯誤习蓬。

  • FILE *fopen(pathname, type【r+b,加號表示讀和寫】)打開一個指定的文件,b區(qū)分文本和二進(jìn)制措嵌,對unix無用躲叼。 cache中用的都是open

  • int fclose(FILE *fp)關(guān)閉一個打開的流。

  • 讀寫結(jié)構(gòu)fread fwrite

  • 一次一行fgets fputs

  • 一次一個字符getc(FILE* fp) fgetc(FILE* fp) getchar(void) getchar等價于getc(stdin)企巢。 出錯或到達(dá)文件尾枫慷,三個函數(shù)返回同樣的值,為了區(qū)分需要ferror(FILE *fp) feof(FILE *fp) void clearerr(FILE *fp)

  • int ungetc(int c, FILE *fp)將字符再壓送回流中浪规。

  • 一次一個字符輸出函數(shù)putc(int c, FILE) fputc(int c, FILE) putchar(int c)

  • 調(diào)用函數(shù)時間長于調(diào)用宏或听;一次系統(tǒng)調(diào)用比普通函數(shù)調(diào)用更費時間。

  • 每次一行io的函數(shù):char fgets(buf,n,FILE)從指定流讀笋婿。 char* gets(buf)從標(biāo)準(zhǔn)輸入讀誉裆。 輸出:fputs(str, FILE) puts(*str)

  • 二進(jìn)制IO:size_t fwrite(&struct[2], sizeof(struct), 4, FILE* fp) 將一個數(shù)組的第2-5號元素寫在一個文件上

  • fread(..) 只能處理統(tǒng)一系統(tǒng)上的數(shù)據(jù),異構(gòu)系統(tǒng)通過網(wǎng)絡(luò)互連時不行缸濒,不同系統(tǒng)間交換二進(jìn)制數(shù)據(jù)需要使用較高級的協(xié)議足丢。

  • 定位流:ftell(FILE) fseek(FILE, offset, whence【SEEK_SET】) rewind(FILE*) fgetpos(..) fsetpos(...) 文件描述符是用lseek

  • int fileno(FILE* fp)獲得文件描述符 , FILE* tmpfile(void)創(chuàng)建臨時文件

  • $TMPDIR=.. ./a.out 在程序名前指定環(huán)境變量

  • int printf(format,...)將格式化數(shù)據(jù)寫到標(biāo)準(zhǔn)輸出庇配。 vprintf(format, va_list arg) vfprintf(...,va_list arg) vsprintf vsnprintf 可變參數(shù)表(...) 變成了arg

  • int fprintf(FILE* fp, format, ...)寫至指定的流

  • int sprintf(buf, format)將格式化的字符串寫入數(shù)組buf中斩跌,在數(shù)組尾端自動加null字節(jié)

  • int snprintf(buf, size_t n,format, ...) 與sprintf基本一樣,n指定了緩沖區(qū)長度捞慌,超過就丟棄避免溢出

  • int scanf(format, ...) sscanf(cmdline【源】, "%s %s", opt[0], opt[1]【目的】)

  • int fscanf(FILE *fp, format, ...)

  • int sscanf(buf, format, ...) vscanf(format, va_list arg)等等

  • struct passwd getpwnam(const char name)獲取口令文件項

  • struct tm結(jié)構(gòu)用于保存時間的年月日的形式耀鸦。

  • gettimeofday(struct timeval *res, NULL)微秒級

  • time_t time(time_t* calptr)返回當(dāng)前時間,calptr不空卿闹,時間值放其中揭糕。

  • struct tm* localtime(const time_t* ptr)他和gmtime(..)的區(qū)別是他把日歷時間轉(zhuǎn)換為本地時區(qū)時間,gmtime轉(zhuǎn)換成國際標(biāo)準(zhǔn)時間锻霎。

  • time_t mktime(struct tm* ptr)以本地時間作為參數(shù)著角,將其轉(zhuǎn)換為time_t值【日歷時間:1970至今】。

  • char asctime(struct tm)返回指向年月日字符串的指針旋恼。char ctime(time_t * prt)返回指向日歷時間的指針吏口。

  • size_t strftime(...)按格式控制時間字符串

  • timeval指定秒和微秒奄容、timespec指定秒和納秒

  • 正常終止一個程序:exit()默認(rèn)包含關(guān)閉流操作【FILE存儲區(qū)清0】 在main中exit(0)等價于return(0)

  • int atexit(void (*func)(void))登記的函數(shù)會被exit函數(shù)以相反的順序調(diào)用。

  • 內(nèi)核執(zhí)行程序的唯一方法是exec产徊。進(jìn)程自愿終止的唯一方法exit【顯式或隱式】昂勒。非自愿的需要給一個信號終止。

  • extern char **environ環(huán)境指針 getenv putenv 訪問特定環(huán)境變量

  • a.out的符號表段舟铜、調(diào)試信息段戈盈、動態(tài)共享庫鏈接表段不裝載到進(jìn)程執(zhí)行的程序映像中。 size a.out 報告正文段谆刨、數(shù)據(jù)段塘娶、bss段的長度

  • cc -static hello1.c 阻止使用共享庫。 cc默認(rèn)使用共享庫

  • void* malloc(size_t size)存儲區(qū)初始值不確定

  • void* calloc(size_t nobj, size_t size)為指定數(shù)量指定長度的對象分配存儲區(qū)痊夭,初始化為0

  • void* realloc(void* ptr, size_t newsize)更改以前的長度刁岸,新增部分初始值不確定,老部分保留內(nèi)容她我。

  • void free(void* ptr)

  • goto語句不能跨越函數(shù)虹曙,setjump longjmp可以處理嵌套調(diào)用中出錯情況【否則只能檢查返回值逐層返回麻煩】。在希望返回的位置int setjmp(jmp_buf env【env為全局才多個函數(shù)可見】),出錯位置int longjmp(env,8)番舆。

  • "str1" "str2"等價于"str1str2"酝碳。為IO庫分配緩沖區(qū)應(yīng)全局靜態(tài)或動態(tài)alloc分配。

  • 編譯器進(jìn)行優(yōu)化時恨狈,它有時會取一些值的時候击敌,直接從寄存器里進(jìn)行存取,而不是從內(nèi)存中獲取拴事,這種優(yōu)化在單線程的程序中沒有問題,但到了多線程程序中圣蝎,由于多個線程是并發(fā)運行的刃宵,就有可能一個線程把某個公共的變量已經(jīng)改變了,這時其余線程中寄存器【線程各自有寄存器】的值已經(jīng)過時徘公,但這個線程本身還不知道牲证,以為沒有改變,仍從寄存器里獲取关面,就導(dǎo)致程序運行會出現(xiàn)未定義的行為坦袍。

  • 自動變量不想回滾,可以定義為volatite【易失】屬性等太。易失屬性告訴編譯器不要優(yōu)化捂齐,在其他地方會改變值,優(yōu)化可能將這個變量一直放到寄存器中缩抡。

  • int getrlimit(int resource, struct rlimit *rlptr) setrlimit可以查詢和更改資源限制奠宜。shell中的ulimit。

  • getpid getppid【獲得父進(jìn)程id】 getuid geteuid getgid getegid【有效組id】

  • pid_t fork(void) fork返回兩次 clone,父返子压真,子返0.父子進(jìn)程執(zhí)行fork之后的代碼娩嚼,父子共享正文不共享數(shù)據(jù),共享文件表和i節(jié)點滴肿。寫時復(fù)制(copy-on-write)寫時復(fù)制岳悟,只讀時共用。

  • vfork在子進(jìn)程調(diào)用exec或exit之前泼差,他在父進(jìn)程的空間中運行贵少,調(diào)用exec或exit之后父進(jìn)程才繼續(xù)運行。

  • 標(biāo)準(zhǔn)IO庫printf是帶緩沖的拴驮。標(biāo)準(zhǔn)輸出連到終端是行緩沖【打印】春瞬,否則是全緩沖。定向到文件是全緩沖

  • 信號可由進(jìn)程自身產(chǎn)生【abort】套啤、其他進(jìn)程【kill(pidid,sig)】或內(nèi)核產(chǎn)生宽气。

  • 父進(jìn)程提前終止的的子進(jìn)程由init【init中默認(rèn)有wait】進(jìn)程領(lǐng)養(yǎng)。內(nèi)核為每個終止的子進(jìn)程保存了一定量的信息潜沦,父進(jìn)程用wait或waitpid得到這些信息萄涯。

  • 一個長期運行的進(jìn)程fork很多子進(jìn)程,除非手動wait唆鸡,否則會出現(xiàn)很多僵死進(jìn)程涝影。

  • pid_t wait(int* statloc) pid_t waitpid(pid_t pid【等待pid號進(jìn)程】, int* statloc【指向終止?fàn)顟B(tài)】, int options)【成功返回進(jìn)程id、0争占、失敗返回-1】燃逻。 如果收到SIGCHLD信號調(diào)用wait,可以立刻返回臂痕,如果任意時刻調(diào)wait伯襟,可能會阻塞直到有一個子進(jìn)程終止。

  • wait3 wait4比waitpid多了一個功能是最后一個參數(shù)會返回所有子進(jìn)程使用資源情況的匯總握童。

  • 競爭條件:多進(jìn)程處理共享數(shù)據(jù)姆怪,數(shù)據(jù)的結(jié)果和處理順序有關(guān)。父等子死用wait澡绩,子等父死 【輪詢】while(getppid() != 1) sleep(1);等于1是init進(jìn)程id稽揭。為1說明父進(jìn)程死了,被init接管了肥卡。

  • exec不創(chuàng)建新進(jìn)程溪掀,進(jìn)程ID不變。exec只是用一個全新的程序替換當(dāng)前進(jìn)程的正文召调、數(shù)據(jù)膨桥、隊蛮浑、棧。execl execv execle execve execlp execvp

  • 所有.c文件查找字符串a(chǎn)bort的指令$ grep abort .//.c

  • 任何時候都可以調(diào)用int setuid(uid_t uid)做下兩種操作:有效用戶ID=實際用戶ID只嚣;有效用戶ID=保存的設(shè)置用戶ID【exec復(fù)制有效用戶ID得來的(一般是文件所有者沮稚?)】。設(shè)置用戶ID的程序册舞,fork后蕴掏,exec之前要改回普通權(quán)限,不應(yīng)使用system函數(shù)调鲸。

  • suspend $fg 作業(yè)控制

  • shell中awk實際是shell先fork->exec(awk)->wait來運行的盛杰。

  • char* getlogin(void)獲取登錄名。找到運行該程序的用戶登錄名getpwuid(getuid())

  • 網(wǎng)絡(luò)登錄telnetd進(jìn)程fork藐石,父負(fù)責(zé)網(wǎng)絡(luò)連接的通信即供,子執(zhí)行l(wèi)ogin,父子間通過偽終端相連接于微。

  • 進(jìn)程組是一個或多個進(jìn)程的集合逗嫡。getpgid setpgid設(shè)置指定進(jìn)程或調(diào)用進(jìn)程的組ID。

  • 會話是一個或多個進(jìn)程組的集合株依。進(jìn)程調(diào)用pid_t setsid(void)建立一個新會話驱证。進(jìn)程是首進(jìn)程、組長恋腕、斷開所有控制終端抹锄。pid_t getsid(pid_t pid)返回會話首進(jìn)程的進(jìn)程組ID。

  • secureCRT是終端荠藤,對應(yīng)前臺進(jìn)程組【終端(終端也是文件描述符)關(guān)聯(lián)的進(jìn)程】伙单,控制進(jìn)程組【shell】,后臺進(jìn)程組【&讓其后臺運行】哈肖,加在一起是會話车份。

  • 一個作業(yè)是幾個進(jìn)程的集合,通常是一個進(jìn)程的管道線牡彻。vi main.c【前臺啟動了一個作業(yè)】 pr *.c | lpr & | make all & 【后臺啟動了兩個作業(yè),兩個作業(yè)調(diào)用的所有進(jìn)程都后臺運行】

  • 終端驅(qū)動程序產(chǎn)生信號進(jìn)而影響前臺進(jìn)程組的方法:中斷字符ctrl+C 退出字符ctrl+\ 掛起字符 ctrl+Z出爹。 可以用信號使后臺作業(yè)暫停庄吼,fg %1 使1號作業(yè)轉(zhuǎn)為前臺作業(yè)

  • 進(jìn)程屬于進(jìn)程組,進(jìn)程組屬于一個會話严就,會話可能有也可能沒有控制終端总寻。前臺進(jìn)程組ID是終端的屬性,不是進(jìn)程的屬性梢为。

  • 管道線的最后一個進(jìn)程是shell的子進(jìn)程渐行,執(zhí)行管道的其他命令都是最后一個進(jìn)程的子進(jìn)程轰坊。前端進(jìn)程組ID==sessionID時說明他是后臺進(jìn)程。

  • 不是孤兒進(jìn)程組的條件:該進(jìn)程組中有一個進(jìn)程祟印,其父進(jìn)程屬于同一個會話的另一個組肴沫。

  • 信號SIGKILL SIGSTOP不能忽略,不能捕捉蕴忆。

  • core文件復(fù)制進(jìn)程終止時的存儲映像颤芬。

  • kill命令和kill函數(shù)只是將一個信號送給一個進(jìn)程或組,進(jìn)程是否終止取決于信號的類型套鹅,以及進(jìn)程是否安排了捕捉該信號站蝠。$kill -USR1 7216

  • void (signal(int signo, void (func)(int)))(int)成功返回信號以前的處理配置,失敗返回SIG_ERR卓鹿。不改變信號的處理方式菱魔,就不能確定信號當(dāng)前的處理方式。func指定SIG_IGN或SIG_DEL表示忽略或默認(rèn)處理吟孙。

  • exec使捕捉失效澜倦,捕捉函數(shù)的地址可能無意義。

  • 進(jìn)程捕捉到信號執(zhí)行信號處理函數(shù)func拔疚,執(zhí)行完后執(zhí)行發(fā)生信號時正在執(zhí)行的代碼【pause函數(shù)能使進(jìn)程掛起直到捕捉到一個信號】肥隆。處理第一次信號后是否將信號動作復(fù)位為默認(rèn)值?

  • read write部分?jǐn)?shù)據(jù)時被中斷算成功還是失敗可以選擇稚失。

  • 在信號處理程序中調(diào)用一個不可重入函數(shù)栋艳,結(jié)果是不可預(yù)見的。

  • raise(int signo) == kill(getpid(), int signo) 進(jìn)程將信號發(fā)送給其他進(jìn)程需要權(quán)限句各。向一個不存在的進(jìn)程發(fā)空信號吸占,kill返回-1.

  • 進(jìn)程ID會重新使用。

  • signal函數(shù)的語義與實現(xiàn)有關(guān)凿宾,最好使用sigaction函數(shù)矾屯。sigaction(signo【要檢測或修改的具體動作的信號編號】, &act【非空則修改其動作】, &oact【非空則返回信號的上一個動作】)

  • sigemptyset(&act.sa_mask)【初始化由set指向的信號集清除其中所有信號】

  • 在處理一個給定的信號時,如果這種信號再次發(fā)生初厚,通常并不將他們排隊件蚕,會被阻塞到對前一個信號處理結(jié)束為止。阻塞結(jié)束后內(nèi)核只傳遞這種信號一次产禾∨抛鳎【屏蔽字為0代表沒有信號阻塞,執(zhí)行哪個信號的處理函數(shù)屏蔽哪個信號】

  • unix低速系統(tǒng)調(diào)用阻塞期間【磁盤IO一般不阻塞】如果接受到一個信號亚情,則該低速系統(tǒng)調(diào)用被中斷妄痪。

  • void abort(void)使異常程序終止。子進(jìn)程終止會向父進(jìn)程發(fā)送SIGCHLD信號楞件。sig2str str2sig是信號編號和信號名相互轉(zhuǎn)換函數(shù)衫生。

  • 多線程程序在單處理器運行仍然能改善響應(yīng)時間和吞吐量裳瘪。

  • 線程ID只在它所屬的進(jìn)程環(huán)境中有效,因此可以不唯一罪针。

  • pthread_t pthread_self(void)獲得自身線程的ID彭羹。主線程可以用線程ID控制哪個線程處理哪些作業(yè)。新線程和主線程之間有競爭站故,使用主線程返回的線程id并不安全皆怕。線程ID如果很長那估計是地址。

  • 如果任一線程調(diào)用exit,_Exit,_exit整個進(jìn)程就會終止西篓。線程終止方式:1.啟動函數(shù)返回愈腾。2被同進(jìn)程其他線程取消【線程可以忽略取消】。3 pthread_exit

  • void pthread_exit(void* rval_ptr) int pthread_join(pthread_t thread, void** rval_ptr【保存線程的終止?fàn)顟B(tài)】)【阻塞直到線程返回】

  • 線程里面聲明的東西別往出帶岂津。線程從線程函數(shù)返回終止虱黄,清理程序就不被調(diào)用。waitpid==pthread_join吮成。pthread_detach使線程分離【對線程終止?fàn)顟B(tài)不感興趣】橱乱,分離線程終止時資源被回收,分離的線程無法pthread_join粱甫。

  • 加鎖的一種場景:對引用計數(shù)加1泳叠、減1以及檢查是否為0之前都要鎖住互斥量〔柘【引用數(shù)類似文件的link】

  • 讀寫鎖以讀模式鎖住是共享模式【并發(fā)讀】危纫,以寫模式鎖住是獨占模式【獨自寫】。

  • 線程的虛擬地址空間是多個線程共用乌庶,如果線程多种蝶,會不夠用。遞歸類型互斥量可以遞歸加鎖瞒大。

  • 線程和信號都涉及函數(shù)可重入的問題螃征。信號:捕捉函數(shù)如果向全局?jǐn)?shù)據(jù)寫會錯。線程:多個線程同時調(diào)用同一函數(shù)透敌。每個線程有各自的信號屏蔽字盯滚。信號處理函數(shù)進(jìn)程內(nèi)共享。

  • errno被重新定義為線程私有數(shù)據(jù)酗电。鍵用來保護(hù)線程私有數(shù)據(jù)淌山。

  • 包含多線程的進(jìn)程fork時只有fork的線程被復(fù)制進(jìn)子進(jìn)程,鎖的情況無法控制顾瞻,如果馬上exec就可以避免。

  • pread(...)使偏移量的設(shè)置和數(shù)據(jù)讀取成為一個原子操作德绿。

  • ps -a【顯示其他用戶所擁有的進(jìn)程狀態(tài)】x【沒有控制終端的進(jìn)程狀態(tài)】j【會話ID荷荤、進(jìn)程組ID退渗。≡棠桑】

  • 創(chuàng)建守護(hù)進(jìn)程兩次fork会油,就不是會話首進(jìn)程,不會取得控制終端古毛。fork保證子進(jìn)程不是進(jìn)程組組長翻翩,可以setsid。

  • lockfile(fd)對文件加鎖 lockf(lockfd, F_TLOCK, 0L)可以確保只有一個守護(hù)進(jìn)程運行稻薇。

  • 低速系統(tǒng)調(diào)用是可能會使進(jìn)程永遠(yuǎn)阻塞的一類系統(tǒng)調(diào)用嫂冻。

  • 非阻塞IO:操作無法完成,立即出錯返回【不停在那塞椎,以便進(jìn)行下一步處理桨仿,類似trylock試加鎖】。兩種方法指定描述符為非阻塞IO:open時O_NONBLOCK案狠;fcntl(fd, cmd, &lock)打開 O_NONBLOCK標(biāo)志服傍。

  • 記錄鎖==字節(jié)范圍鎖:當(dāng)一個進(jìn)程讀或修改文件某部分時,可以阻止其他進(jìn)程修改同一文件區(qū)骂铁。有些系統(tǒng)中文件的最后狀態(tài)取決于寫該文件的最后一個進(jìn)程吹零。

  • 同一進(jìn)程可對同一字節(jié)范圍重復(fù)加鎖,新鎖換老鎖拉庵〔右危可以測試另一個進(jìn)程是否對某記錄加鎖。

  • 鎖是與進(jìn)程名段、文件兩者相關(guān)聯(lián)的阱扬。fork出的子進(jìn)程不繼承父進(jìn)程對文件的鎖【避免父子同時寫一個文件】。exec新程序繼承原程序的鎖伸辟。

  • 某些unix提供系統(tǒng)調(diào)用跟蹤特性麻惶。

  • STREAM:構(gòu)造內(nèi)核設(shè)備驅(qū)動程序和網(wǎng)絡(luò)協(xié)議包的一種通用方法。

  • IO多路轉(zhuǎn)接【兩個描述符】:執(zhí)行阻塞read信夫,阻塞是對整個進(jìn)程阻塞窃蹋,如果多個通路【一般是無限循環(huán)讀、寫】想要相互不影響静稻,就得fork多個進(jìn)程警没,每個進(jìn)程處理各自的文件描述符。用非阻塞read輪詢描述符消耗cpu振湾。

  • IO多路轉(zhuǎn)接思想:構(gòu)造一張描述符表杀迹,調(diào)用一個函數(shù),直到表中描述符中的一個已經(jīng)準(zhǔn)備好IO時押搪,該函數(shù)返回树酪,告訴進(jìn)程哪些描述符可以IO浅碾。主要用于終端IO和網(wǎng)絡(luò)IO。select(0, NULL, NULL, NULL, &tv)相當(dāng)于sleep了续语,精確到微秒垂谢。

  • 異步IO:基本思想,告訴內(nèi)核,當(dāng)一個描述符已準(zhǔn)備好可以進(jìn)行IO時疮茄,用一個信號通知它【它指應(yīng)用程序】滥朱。系統(tǒng)V異步IO調(diào)ioctl設(shè)置信號處理,只對STREAMS設(shè)備和STREAMS管道起作用力试。 BSD異步IO設(shè)置信號SIGIO處理程序徙邻,調(diào)fcntl設(shè)置O_ASYNC文件為異步IO。只對終端和網(wǎng)絡(luò)描述符有效懂版。

  • 存儲映射IO:【將一個給定文件映射到一個存儲區(qū)域】unsigned char* mmapBuf = (unsigned char)mmap(NULL【區(qū)域起始地址】, fileSize, PROT_READ【映射區(qū)可讀】, MAP_SHARED ,fd【被映射文件】, 0【映射字節(jié)在文件中起始偏移量】) munmap((char)mmapBuf, fileSize)【解除映射】 msync沖洗到磁盤

  • IPC【InterProcess Communication】:各種管道鹃栽、消息隊列、信號量躯畴、共享存儲民鼓、套接字、STREAMS【僅后兩種支持不同主機(jī)進(jìn)程間通信】

  • 管道:半雙工【數(shù)據(jù)只能在一個方向上流動】蓬抄;只能在公共祖先的進(jìn)程間使用丰嘉,通常fork后父子間使用。int pipe(int filedes[2]) fork后f[0]<-【內(nèi)核自動嚷缭?】-f[1] 有兩份饮亏,各關(guān)閉一個

  • sh -c cmdstring表示shell將擴(kuò)展字符串中的特殊字符【*.c】。

  • ${PAGE:-more}如果PAGE已定義阅爽,使用路幸,否則用more。

  • 對管道標(biāo)準(zhǔn)IO默認(rèn)全緩沖付翁。

  • 通過FIFO【命名管道】不相關(guān)的進(jìn)程也能交換數(shù)據(jù)简肴。int mkfifo(pathname, mode_t mode)類似于創(chuàng)建普通文件。

  • 創(chuàng)建IPC結(jié)構(gòu):msgget semget shmget 要指定一個鍵key_t百侧。 ftok可由一個路徑名和項目ID產(chǎn)生一個鍵key_t ftok(path, id)

  • msgctl semctl shmctl修改uid砰识、gid、mode 三種IPC都有內(nèi)置限制佣渴,可通過配置內(nèi)核修改辫狼。 ipcs查看 ipcrm刪除

  • msgrcv可以是非先進(jìn)先出

  • 信號量的值代表對應(yīng)資源是否可以使用。semop(_ID, buf[]【數(shù)組中操作要么都執(zhí)行辛润,要么都不執(zhí)行】, 1)表示等待信號量膨处、釋放資源、獲取資源。semctl取信號量信息真椿、設(shè)置信號量信息秦叛。

  • 使用信號量【實際上是同步原語而不是IPC】,先創(chuàng)建一個包含一個成員的信號量集合瀑粥,信號量值賦初值1.分配資源時sem_op為-1調(diào)用semop,釋放資源sem_op為1調(diào)用semop三圆。每次設(shè)置SEM_UNDO狞换,以處理進(jìn)程終止還有未釋放資源的情況。

  • shmget既可以創(chuàng)建舟肉,也可以引用已有的【msgget一樣】修噪。 shmctl IPC_RMID減少引用數(shù),不真正刪除路媚。shmid和pickey不一樣黄琼,shmget返回值是shmid 。shmdt脫接不刪除整慎,引用數(shù)減一脏款。

  • 套接字用于不同計算機(jī)上的進(jìn)程相互通信,其它進(jìn)程運行位置透明裤园〕肥Γ可以采用許多網(wǎng)絡(luò)協(xié)議,TCP/IP常見拧揽。

  • 創(chuàng)建一個套接字int socket(int domain【例如ipv4internet網(wǎng)域】, int type, int protocol)返回套接字文件描述符剃盾。

  • int shutdown(int sockfd, int how)禁止套接字上的輸入輸出。uint32_t htonl(uint32_t hostint32)等進(jìn)行處理器字節(jié)序和網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換淤袜。

  • inet_pton( AF_INET, host.c_str(), &m_addr.sin_addr)將文本字符串轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)序的二進(jìn)制地址

  • poll select函數(shù)能檢查文件描述符的狀態(tài)痒谴,用來決定是否對文件描述符執(zhí)行某種操作。

  • setsockopt(_sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len)

  • int fattach(int fileds, const char* path)使STREAMS管道和文件系統(tǒng)中的一個名字關(guān)聯(lián)铡羡。

  • unix域套接字用于同一機(jī)器上進(jìn)程間通信积蔚。int ssocketpair(int domain, int type, int protocol, int sockfd[2])

  • 終端IO:函數(shù)tcgetattr tcsetattr 終端IO控制函數(shù)大多tc開頭

  • 很多數(shù)據(jù)庫實現(xiàn)都采用兩個文件:索引文件和數(shù)據(jù)文件。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蓖墅,一起剝皮案震驚了整個濱河市库倘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌论矾,老刑警劉巖教翩,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贪壳,居然都是意外死亡饱亿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪笼,“玉大人钻注,你說我怎么就攤上這事∨涿ǎ” “怎么了幅恋?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泵肄。 經(jīng)常有香客問我捆交,道長,這世上最難降的妖魔是什么腐巢? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任品追,我火速辦了婚禮,結(jié)果婚禮上冯丙,老公的妹妹穿的比我還像新娘肉瓦。我一直安慰自己,他們只是感情好胃惜,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布泞莉。 她就那樣靜靜地躺著,像睡著了一般蛹疯。 火紅的嫁衣襯著肌膚如雪戒财。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天捺弦,我揣著相機(jī)與錄音饮寞,去河邊找鬼。 笑死列吼,一個胖子當(dāng)著我的面吹牛幽崩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寞钥,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼慌申,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了理郑?” 一聲冷哼從身側(cè)響起蹄溉,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎您炉,沒想到半個月后柒爵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡赚爵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年棉胀,在試婚紗的時候發(fā)現(xiàn)自己被綠了法瑟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腥沽。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡揖闸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出审残,到底是詐尸還是另有隱情麻掸,我是刑警寧澤酥夭,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站脊奋,受9級特大地震影響采郎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狂魔,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淫痰。 院中可真熱鬧最楷,春花似錦、人聲如沸待错。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽火俄。三九已至犯建,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓜客,已是汗流浹背适瓦。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留谱仪,地道東北人玻熙。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像疯攒,于是被迫代替她去往敵國和親嗦随。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

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