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ù)文件。
本文幫你在 Unix 下玩轉(zhuǎn) C 語言
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彪笼,“玉大人钻注,你說我怎么就攤上這事∨涿ǎ” “怎么了幅恋?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長泵肄。 經(jīng)常有香客問我捆交,道長,這世上最難降的妖魔是什么腐巢? 我笑而不...
- 正文 為了忘掉前任品追,我火速辦了婚禮,結(jié)果婚禮上冯丙,老公的妹妹穿的比我還像新娘肉瓦。我一直安慰自己,他們只是感情好胃惜,可當(dāng)我...
- 文/花漫 我一把揭開白布泞莉。 她就那樣靜靜地躺著,像睡著了一般蛹疯。 火紅的嫁衣襯著肌膚如雪戒财。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼慌申,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了理郑?” 一聲冷哼從身側(cè)響起蹄溉,我...
- 正文 年R本政府宣布,位于F島的核電站脊奋,受9級特大地震影響采郎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狂魔,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淫痰。 院中可真熱鬧最楷,春花似錦、人聲如沸待错。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽火俄。三九已至犯建,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓜客,已是汗流浹背适瓦。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- UNIX基礎(chǔ)知識 UNIX體系結(jié)構(gòu) 登陸 文件和目錄文件系統(tǒng)【1敬尺、目錄是一個包含目錄項的文件枚尼;2、根目錄:所有東西...
- UNIX期末總復(fù)習(xí) (1)什么是操作系統(tǒng)砂吞?什么是UNIX操作系統(tǒng)署恍?什么是Linux操作系統(tǒng)?它們之間的關(guān)系是怎樣的...
- 最近重新學(xué)習(xí)APUE呜舒,特開文章做學(xué)習(xí)筆記apue.h被我封裝在all.h中锭汛,apue配置可以參見我的另一篇文章[C...
- 前言 苦逼本科生要考試笨奠,考試還奇難內(nèi)容齊多 這里我整理一下考試提綱 正好這也是對《unix環(huán)境高級編程》的前半部分...
- POSIX官網(wǎng) POSIX是所有unix-like系統(tǒng)都需要遵循的規(guī)范,其定義了操作系統(tǒng)需要提供的接口唤殴,官網(wǎng)在 (...