-
shell是一種特殊的應用程式(命令列直譯器),他為執行其他應用程式提供了一個介面。
-
posix規範了作業系統是什麼樣
-
每個程式都有一個工作目錄(又叫當前目錄),相對路徑都是從工作目錄開始解釋。
-
Ctrl+D是檔案結束字元
-
read讀指定位元組數;fgets是讀取一行
-
三個程式控制函式:fork exec waitpid。 waitpid【此函式獲取資訊,釋放資源】父程式等待子程式終止,可以得到子程式何時終止。system函式是在exec外包了一層。
-
execlp要求引數以null結束,換行符不可以
-
執行緒id只在它所屬程式內起作用,在另一個程式中無意義,可以使用執行緒id引用相應的執行緒。
-
一個使用者可以屬於多至16個組
-
ctrl+c中斷鍵,ctrl+\退出鍵,等價於kill函式。kill(pid, SIGTERM)向另一程式發訊號,發起訊號的必須是該程式的所有者。
-
(gdb)set follow-fork-mode child使gdb進入子程式,事實證明不設定(預設除錯父程式)這句無法進入pid==0的語句塊。子程式exit後無法再設定斷點gdb資訊丟失,此時run可能啟動的不是父程式而是孫程式。
-
fork會複製fork開始直到函式結束的程式碼【共享程式碼正文,但複製全部變數】
-
日曆時間:1970至今秒數,time_t型別用於儲存這種時間。
-
程式時間:cpu時間,clock_t型別用於儲存這種時間。
-
系統cpu時間是程式執行核心程式的時間。執行使用者指令的時間是使用者cpu時間。兩者之和是cpu時間。時鐘時間【牆上鍾時間】,是程式執行的時間總量,和程式數有關。time ls【ls可換成任意程式名】 檢視時間。
-
clock_t times(struct tms* buf)成功返回牆上鍾時間【必須使用相對值,做差】
-
庫函式不一定呼叫系統呼叫。應用程式可以直接呼叫系統呼叫,也可以通過C庫函式呼叫系統呼叫。
-
ISO C標準有24個標頭檔案(包括stdlib.h,stdio.h)。
-
介面即協議。
-
很多程式需要為路徑分配儲存區
-
守護程式:後臺執行且不與終端相連線的一種程式。
-
與檔案或目錄無關的選項用sysconf確定,與檔案或目錄有關的選項用pathconf,fpathconf確定。
-
unix系統的大多數檔案I/O只需要用到5個函式:open close read write lseek,都是不帶緩衝的I/O。不帶緩衝指的是read write都呼叫核心的一個系統呼叫。不帶緩衝的io不是iso c的組成部分,是posix的組成部分。
-
對核心而言,所有的開啟的檔案都通過檔案描述符(非負整數)引用。0 1 2 分別是輸入 輸出 錯誤 的描述符。檔案描述符變化範圍0-OPEN_MAX(表示每個程式可以開啟OPEN_MAX個檔案)。
-
open函式:int fileId【返回最小的未用檔案描述符數值】 = open(tmpPtr->_fileName【檔名】,O_RDWR【讀、寫開啟】|O_CREAT【如果不存在則建立】, 0666【配合O_CREATE指定新檔案訪問許可權】);
-
close(fileId);關閉檔案同時釋放程式加在該檔案上的所有記錄鎖。程式終止時核心自動關閉它開啟的檔案。
-
返回檔案偏移量【偏移量始終存在,讀、寫操作從它指向的位置開始】=lseek(fileId,offset【每一個開啟的檔案都有一個當前檔案偏移量,預設0,除非指定O_APPEND】,SEEK_SET【將偏移量設為檔案開始處offset位元組】)
-
lseek返回-1說明檔案描述符對應的檔案是管道、fifo或網路套接字。某些裝置允許負的偏移量。
-
od -c 檔名 【-c表示以字元方式列印檔案內容】 ls -ls 檢視檔案佔用多少個磁碟塊
-
nRead【返回讀到位元組數】 = read(flag_fd【檔案描述符】, buffer【讀取資料到buffer中】, length【一次讀取位元組數】) 【成功返回前,偏移量增加讀到的位元組數】
-
int bytes_write【返回寫入位元組數】 = write(fileHandle,ptr,writeSize【寫入位元組數】) 【寫操作從當前偏移量開始,成功後偏移量自動增加寫入位元組數】
-
測量檔案讀寫由於快取機制,在第一次之後可能不準確。
-
每個程式都有一張開啟檔案描述符表->檔案表(當前檔案偏移量)->v節點資訊
-
可能有多個檔案描述符指向同一檔案表項,多個檔案表項指向一個v節點表。多程式讀同一個檔案沒有問題,但是寫同一個檔案會有問題->原子操作。
-
open中用O_CREAT和O_EXCL可以將測試和建立合併為一個原子操作。原子操作指多步組成的操作要麼執行完所有步驟,要麼一步也不執行。
-
先lseek再write不可能是原子操作。兩個函式間核心可以掛起程式。
-
pread(..., off_t offset) pwrite(..., off_t offset) 相當於順序呼叫lseek和read,與順序呼叫的區別:無法中斷、不更新檔案指標
-
O_APPEND方式開啟檔案,每次write,檔案偏移量自動定位到檔案尾。
-
新的檔案描述符 = dup(int filedes) dup2(int filedes【被複制】,int filedes2【指定數值】) 複製現存的檔案描述符,與引數filedes共享同一個檔案表項。fcntl(..)也可以複製檔案描述符。
-
sync將塊緩衝區排入寫佇列,不等實際寫磁碟。fsync對單一檔案起作用,等寫磁碟結束返回,更新屬性。fdatasync隻影響檔案的資料部分。
-
fcntl(..)返回值和命令有關,可以返回檔案狀態,檔案描述符。可以修改檔案狀態。
-
5<>temp表示在檔案描述符5上開啟檔案供讀寫。
-
終端I/O是 ioctl的最大使用方面。
-
digit1 > &digit2表示要將digit1重定向至描述符2的同一個檔案。
-
shell從左到右處理命令
-
struct stat sA【stat結構體包含磁碟號,所有者,訪問修改時間等屬性】; int retA【返回小於0表示檔案不存在】 = stat(fileNameA.c_str(),&sA【stat函式將填寫sA】); ls -l就是使用的stat(...)函式
-
lstat(...)的增強功能是檢測符號連結
-
檔案型別資訊包含在stat結構的st_mode成員中,有下面幾種型別。
普通檔案【包含某種資料的檔案,資料是文字還是二進位制對核心而言無區別,對檔案內容的解釋由處理該檔案的應用程式進行。例外:二進位制可執行檔案遵守核心理解的統一格式】
目錄檔案【包含其他檔案的名字以及指向與這些檔案有關資訊的指標】
塊裝置檔案【磁碟,提供對裝置帶緩衝的訪問】
字元裝置檔案【鍵盤,提供對裝置不帶緩衝的訪問】
FIFO 又名管道檔案,shell裡的豎線 | 【用於程式間通訊】
套接字【這種檔案用於程式間的網路通訊,也可用於一臺機上程式間的非網路通訊】
符號連結【這種檔案型別指向另一個檔案】 -
程式間通訊(IPC)物件也表示為檔案:訊息佇列、訊號量、共享儲存物件。
-
執行一個程式時exec(...)會儲存有效使用者ID和有效組ID。通常有效ID==實際ID。
-
當檔案的有效使用者ID設定為檔案所有者ID時,如果所有者為root,即使被一個普通使用者執行,該程式也具有超級許可權。
-
檔案訪問許可權:第一個規則是我們用名字開啟一個檔案時,對該名字包含的每一個目錄,包括她可能隱含的當前工作目錄(./)都應具有執行許可權。對檔案有適當的許可權,取決於以何種方式開啟。
-
對目錄的讀許可權使我們可以獲得該目錄所有檔名列表。對目錄的執行許可權使我們可以通過該目錄,也就是【搜尋】該目錄,尋找一個特定的檔名。
-
建立檔案需要對目錄有寫許可權和可執行許可權。刪除檔案需要對目錄有寫和可執行許可權【實際是減少檔案i節點的一個連線數而已,檔案本身還存在】,對檔案本身不需要有讀、寫許可權【刪除對檔案本身沒讀沒寫】。
-
新檔案的使用者ID設定為程式的有效使用者ID。新檔案的組ID可以是:1.程式的有效組ID。2.它所在目錄的組ID。
-
access(pathname, mode)按實際使用者ID,和實際組ID進行訪問許可權測試。只有root能chown.
-
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);設定程式的檔案模式建立遮蔽字
creat("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH)
先後執行上面兩行的執行結果-rw------- bar
chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) fchmod(fildes, mod)
執行結果-rw-r--r-- bar -
-rw-rwSrw- S表示設定組ID【有效使用者ID和組ID】位已設定【有效使用者ID變成檔案所有者的ID】,同時,組執行位則未設定。
-
linux交換區==windows下虛擬記憶體
-
chmod a+t 目錄 設定粘住位
-
粘住位:可執行程式正文副本儲存在交換區。目錄設定了粘住位,只有對目錄有寫許可權加上1.擁有檔案;2.擁有目錄;3.root三種之一 才可以刪除或更名目錄下的檔案。
-
chown fchown lchown更改檔案使用者ID
-
truncate(pathnane, length) ftruncate(filedes, length) 截斷檔案或建立空洞
-
磁碟可分為多個區,不同的區有不同的檔案系統。
-
目錄項【目錄/檔名】->i節點->實際資料塊。多個目錄項可以指向同一個i節點,例如軟連線和目錄本身指向的是同一塊資料,就應該指向的是同一個i節點。mv只更改目錄名,不移動實際資料。
-
link(existpath, newpath)建立一個新的目錄項,增加連結數;unlink(pathname)刪除目錄項,將pathname所引用的檔案連結數減1. 目錄項刪除後看不見檔案,但檔案仍有可能佔據磁碟空間直至被核心刪除。
-
./a.out & 表示後臺執行
-
如果開啟檔案的程式數和連結數同時為0,核心會刪除該檔案。
-
remove(pathname)解除對一個目錄或檔案的連結。rename(oldname, newname)
-
普通目錄項和檔案本身的關係是硬連結,她直接指向檔案的i節點。符號連結是指向一個檔案的間接指標,可以跨不同的檔案系統。要注意函式是否跟隨符號連結。
-
symlink(actualpath, sympath)建立符號連結。readlink(pathname, buf, bufsize)開啟連結本身,並讀連結中的名字。
-
ls -lt預設按檔案修改時間排序,-u按訪問時間,-c按更改狀態時間。utime(pathname, times)更改檔案的訪問和更改時間。
-
mkdir(pathname, mode)建立一個新的空目錄。rmdir(pathname)刪除一個空目錄。
-
DIR *opendir(pathname) struct dirent *readdir(DIR *dp) chdir(...)【當前工作目錄是程式的一個屬性,chdir隻影響程式本身】 fchdir(...) getcwd(...)獲得完整絕對路徑
-
標準I/O庫【ISO C標準】檔案操作圍繞檔案描述符,也可以理解成圍繞流(stream)。當用標準io開啟或建立一個檔案時,我們已使一個流與檔案關聯。標準IO最終都要呼叫read,write。
-
FILE結構包含:檔案描述符、緩衝區指標、緩衝區長度、當前緩衝區位元組數以及出錯標誌。檔案指標是FILE*
-
標準輸入輸出的檔案指標是stdin,stdout,stderr。io庫提供緩衝的目的是減少使用read和write的呼叫次數。標準io函式通常呼叫malloc獲得緩衝區。
-
setbuf(FILE* , buf, mode ,size)更改緩衝型別。 fflus(FILE *fp)此函式使該流所有未寫的資料都被傳送至核心。
-
FILE *fdopen(filedes, type)使已有的檔案描述符和流關聯。
-
FILE *freopen(pathname, type, FILE *restrict fp)在一個指定的流上開啟檔案,若流已開啟,先關閉流。一般用於將指定檔案開啟為一個預定義的流:輸入,輸出,錯誤。
-
FILE *fopen(pathname, type【r+b,加號表示讀和寫】)開啟一個指定的檔案,b區分文字和二進位制,對unix無用。 cache中用的都是open
-
int fclose(FILE *fp)關閉一個開啟的流。
-
讀寫結構fread fwrite
-
一次一行fgets fputs
-
一次一個字元getc(FILE* fp) fgetc(FILE* fp) getchar(void) getchar等價於getc(stdin)。 出錯或到達檔案尾,三個函式返回同樣的值,為了區分需要ferror(FILE *fp) feof(FILE *fp) void clearerr(FILE *fp)
-
int ungetc(int c, FILE *fp)將字元再壓送回流中。
-
一次一個字元輸出函式putc(int c, FILE) fputc(int c, FILE) putchar(int c)
-
呼叫函式時間長於呼叫巨集;一次系統呼叫比普通函式呼叫更費時間。
-
每次一行io的函式:char fgets(buf,n,FILE)從指定流讀。 char* gets(buf)從標準輸入讀。 輸出:fputs(str, FILE) puts(*str)
-
二進位制IO:size_t fwrite(&struct[2], sizeof(struct), 4, FILE* fp) 將一個陣列的第2-5號元素寫在一個檔案上
-
fread(..) 只能處理統一系統上的資料,異構系統通過網路互連時不行,不同系統間交換二進位制資料需要使用較高階的協議。
-
定位流:ftell(FILE) fseek(FILE, offset, whence【SEEK_SET】) rewind(FILE*) fgetpos(..) fsetpos(...) 檔案描述符是用lseek
-
int fileno(FILE* fp)獲得檔案描述符 , FILE* tmpfile(void)建立臨時檔案
-
$TMPDIR=.. ./a.out 在程式名前指定環境變數
-
int printf(format,...)將格式化資料寫到標準輸出。 vprintf(format, va_list arg) vfprintf(...,va_list arg) vsprintf vsnprintf 可變參數列(...) 變成了arg
-
int fprintf(FILE* fp, format, ...)寫至指定的流
-
int sprintf(buf, format)將格式化的字串寫入陣列buf中,在陣列尾端自動加null位元組
-
int snprintf(buf, size_t n,format, ...) 與sprintf基本一樣,n指定了緩衝區長度,超過就丟棄避免溢位
-
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結構用於儲存時間的年月日的形式。
-
gettimeofday(struct timeval *res, NULL)微秒級
-
time_t time(time_t* calptr)返回當前時間,calptr不空,時間值放其中。
-
struct tm* localtime(const time_t* ptr)他和gmtime(..)的區別是他把日曆時間轉換為本地時區時間,gmtime轉換成國際標準時間。
-
time_t mktime(struct tm* ptr)以本地時間作為引數,將其轉換為time_t值【日曆時間:1970至今】。
-
char asctime(struct tm)返回指向年月日字串的指標。char ctime(time_t * prt)返回指向日曆時間的指標。
-
size_t strftime(...)按格式控制時間字串
-
timeval指定秒和微秒、timespec指定秒和納秒
-
正常終止一個程式:exit()預設包含關閉流操作【FILE儲存區清0】 在main中exit(0)等價於return(0)
-
int atexit(void (*func)(void))登記的函式會被exit函式以相反的順序呼叫。
-
核心執行程式的唯一方法是exec。程式自願終止的唯一方法exit【顯式或隱式】。非自願的需要給一個訊號終止。
-
extern char **environ環境指標 getenv putenv 訪問特定環境變數
-
a.out的符號表段、除錯資訊段、動態共享庫連結表段不裝載到程式執行的程式映像中。 size a.out 報告正文段、資料段、bss段的長度
-
cc -static hello1.c 阻止使用共享庫。 cc預設使用共享庫
-
void* malloc(size_t size)儲存區初始值不確定
-
void* calloc(size_t nobj, size_t size)為指定數量指定長度的物件分配儲存區,初始化為0
-
void* realloc(void* ptr, size_t newsize)更改以前的長度,新增部分初始值不確定,老部分保留內容。
-
void free(void* ptr)
-
goto語句不能跨越函式,setjump longjmp可以處理巢狀呼叫中出錯情況【否則只能檢查返回值逐層返回麻煩】。在希望返回的位置int setjmp(jmp_buf env【env為全域性才多個函式可見】),出錯位置int longjmp(env,8)。
-
"str1" "str2"等價於"str1str2"。為IO庫分配緩衝區應全域性靜態或動態alloc分配。
-
編譯器進行優化時,它有時會取一些值的時候,直接從暫存器裡進行存取,而不是從記憶體中獲取,這種優化在單執行緒的程式中沒有問題,但到了多執行緒程式中,由於多個執行緒是併發執行的,就有可能一個執行緒把某個公共的變數已經改變了,這時其餘執行緒中暫存器【執行緒各自有暫存器】的值已經過時,但這個執行緒本身還不知道,以為沒有改變,仍從暫存器裡獲取,就導致程式執行會出現未定義的行為。
-
自動變數不想回滾,可以定義為volatite【易失】屬性。易失屬性告訴編譯器不要優化,在其他地方會改變值,優化可能將這個變數一直放到暫存器中。
-
int getrlimit(int resource, struct rlimit *rlptr) setrlimit可以查詢和更改資源限制。shell中的ulimit。
-
getpid getppid【獲得父程式id】 getuid geteuid getgid getegid【有效組id】
-
pid_t fork(void) fork返回兩次 clone,父返子,子返0.父子程式執行fork之後的程式碼,父子共享正文不共享資料,共享檔案表和i節點。寫時複製(copy-on-write)寫時複製,只讀時共用。
-
vfork在子程式呼叫exec或exit之前,他在父程式的空間中執行,呼叫exec或exit之後父程式才繼續執行。
-
標準IO庫printf是帶緩衝的。標準輸出連到終端是行緩衝【列印】,否則是全緩衝。定向到檔案是全緩衝
-
訊號可由程式自身產生【abort】、其他程式【kill(pidid,sig)】或核心產生。
-
父程式提前終止的的子程式由init【init中預設有wait】程式領養。核心為每個終止的子程式儲存了一定量的資訊,父程式用wait或waitpid得到這些資訊。
-
一個長期執行的程式fork很多子程式,除非手動wait,否則會出現很多僵死程式。
-
pid_t wait(int* statloc) pid_t waitpid(pid_t pid【等待pid號程式】, int* statloc【指向終止狀態】, int options)【成功返回程式id、0、失敗返回-1】。 如果收到SIGCHLD訊號呼叫wait,可以立刻返回,如果任意時刻調wait,可能會阻塞直到有一個子程式終止。
-
wait3 wait4比waitpid多了一個功能是最後一個引數會返回所有子程式使用資源情況的彙總。
-
競爭條件:多程式處理共享資料,資料的結果和處理順序有關。父等子死用wait,子等父死 【輪詢】while(getppid() != 1) sleep(1);等於1是init程式id。為1說明父程式死了,被init接管了。
-
exec不建立新程式,程式ID不變。exec只是用一個全新的程式替換當前程式的正文、資料、隊、棧。execl execv execle execve execlp execvp
-
所有.c檔案查詢字串abort的指令$ grep abort .//.c
-
任何時候都可以呼叫int setuid(uid_t uid)做下兩種操作:有效使用者ID=實際使用者ID;有效使用者ID=儲存的設定使用者ID【exec複製有效使用者ID得來的(一般是檔案所有者?)】。設定使用者ID的程式,fork後,exec之前要改回普通許可權,不應使用system函式。
-
suspend $fg 作業控制
-
shell中awk實際是shell先fork->exec(awk)->wait來執行的。
-
char* getlogin(void)獲取登入名。找到執行該程式的使用者登入名getpwuid(getuid())
-
網路登入telnetd程式fork,父負責網路連線的通訊,子執行login,父子間通過偽終端相連線。
-
程式組是一個或多個程式的集合。getpgid setpgid設定指定程式或呼叫程式的組ID。
-
會話是一個或多個程式組的集合。程式呼叫pid_t setsid(void)建立一個新會話。程式是首程式、組長、斷開所有控制終端。pid_t getsid(pid_t pid)返回會話首程式的程式組ID。
-
secureCRT是終端,對應前臺程式組【終端(終端也是檔案描述符)關聯的程式】,控制程式組【shell】,後臺程式組【&讓其後臺執行】,加在一起是會話。
-
一個作業是幾個程式的集合,通常是一個程式的管道線。vi main.c【前臺啟動了一個作業】 pr *.c | lpr & | make all & 【後臺啟動了兩個作業,兩個作業呼叫的所有程式都後臺執行】
-
終端驅動程式產生訊號進而影響前臺程式組的方法:中斷字元ctrl+C 退出字元ctrl+\ 掛起字元 ctrl+Z。 可以用訊號使後臺作業暫停,fg %1 使1號作業轉為前臺作業
-
程式屬於程式組,程式組屬於一個會話,會話可能有也可能沒有控制終端。前臺程式組ID是終端的屬性,不是程式的屬性。
-
管道線的最後一個程式是shell的子程式,執行管道的其他命令都是最後一個程式的子程式。前端程式組ID==sessionID時說明他是後臺程式。
-
不是孤兒程式組的條件:該程式組中有一個程式,其父程式屬於同一個會話的另一個組。
-
訊號SIGKILL SIGSTOP不能忽略,不能捕捉。
-
core檔案複製程式終止時的儲存映像。
-
kill命令和kill函式只是將一個訊號送給一個程式或組,程式是否終止取決於訊號的型別,以及程式是否安排了捕捉該訊號。$kill -USR1 7216
-
void (signal(int signo, void (func)(int)))(int)成功返回訊號以前的處理配置,失敗返回SIG_ERR。不改變訊號的處理方式,就不能確定訊號當前的處理方式。func指定SIG_IGN或SIG_DEL表示忽略或預設處理。
-
exec使捕捉失效,捕捉函式的地址可能無意義。
-
程式捕捉到訊號執行訊號處理函式func,執行完後執行發生訊號時正在執行的程式碼【pause函式能使程式掛起直到捕捉到一個訊號】。處理第一次訊號後是否將訊號動作復位為預設值?
-
read write部分資料時被中斷算成功還是失敗可以選擇。
-
在訊號處理程式中呼叫一個不可重入函式,結果是不可預見的。
-
raise(int signo) == kill(getpid(), int signo) 程式將訊號傳送給其他程式需要許可權。向一個不存在的程式發空訊號,kill返回-1.
-
程式ID會重新使用。
-
signal函式的語義與實現有關,最好使用sigaction函式。sigaction(signo【要檢測或修改的具體動作的訊號編號】, &act【非空則修改其動作】, &oact【非空則返回訊號的上一個動作】)
-
sigemptyset(&act.sa_mask)【初始化由set指向的訊號集清除其中所有訊號】
-
在處理一個給定的訊號時,如果這種訊號再次發生,通常並不將他們排隊,會被阻塞到對前一個訊號處理結束為止。阻塞結束後核心只傳遞這種訊號一次。【遮蔽字為0代表沒有訊號阻塞,執行哪個訊號的處理函式遮蔽哪個訊號】
-
unix低速系統呼叫阻塞期間【磁碟IO一般不阻塞】如果接受到一個訊號,則該低速系統呼叫被中斷。
-
void abort(void)使異常程式終止。子程式終止會向父程式傳送SIGCHLD訊號。sig2str str2sig是訊號編號和訊號名相互轉換函式。
-
多執行緒程式在單處理器執行仍然能改善響應時間和吞吐量。
-
執行緒ID只在它所屬的程式環境中有效,因此可以不唯一。
-
pthread_t pthread_self(void)獲得自身執行緒的ID。主執行緒可以用執行緒ID控制哪個執行緒處理哪些作業。新執行緒和主執行緒之間有競爭,使用主執行緒返回的執行緒id並不安全。執行緒ID如果很長那估計是地址。
-
如果任一執行緒呼叫exit,_Exit,_exit整個程式就會終止。執行緒終止方式:1.啟動函式返回。2被同程式其他執行緒取消【執行緒可以忽略取消】。3 pthread_exit
-
void pthread_exit(void* rval_ptr) int pthread_join(pthread_t thread, void** rval_ptr【儲存執行緒的終止狀態】)【阻塞直到執行緒返回】
-
執行緒裡面宣告的東西別往出帶。執行緒從執行緒函式返回終止,清理程式就不被呼叫。waitpid==pthread_join。pthread_detach使執行緒分離【對執行緒終止狀態不感興趣】,分離執行緒終止時資源被回收,分離的執行緒無法pthread_join。
-
加鎖的一種場景:對引用計數加1、減1以及檢查是否為0之前都要鎖住互斥量。【引用數類似檔案的link】
-
讀寫鎖以讀模式鎖住是共享模式【併發讀】,以寫模式鎖住是獨佔模式【獨自寫】。
-
執行緒的虛擬地址空間是多個執行緒共用,如果執行緒多,會不夠用。遞迴型別互斥量可以遞迴加鎖。
-
執行緒和訊號都涉及函式可重入的問題。訊號:捕捉函式如果向全域性資料寫會錯。執行緒:多個執行緒同時呼叫同一函式。每個執行緒有各自的訊號遮蔽字。訊號處理函式程式內共享。
-
errno被重新定義為執行緒私有資料。鍵用來保護執行緒私有資料。
-
包含多執行緒的程式fork時只有fork的執行緒被複制進子程式,鎖的情況無法控制,如果馬上exec就可以避免。
-
pread(...)使偏移量的設定和資料讀取成為一個原子操作。
-
ps -a【顯示其他使用者所擁有的程式狀態】x【沒有控制終端的程式狀態】j【會話ID、程式組ID。。】
-
建立守護程式兩次fork,就不是會話首程式,不會取得控制終端。fork保證子程式不是程式組組長,可以setsid。
-
lockfile(fd)對檔案加鎖 lockf(lockfd, F_TLOCK, 0L)可以確保只有一個守護程式執行。
-
低速系統呼叫是可能會使程式永遠阻塞的一類系統呼叫。
-
非阻塞IO:操作無法完成,立即出錯返回【不停在那,以便進行下一步處理,類似trylock試加鎖】。兩種方法指定描述符為非阻塞IO:open時O_NONBLOCK;fcntl(fd, cmd, &lock)開啟 O_NONBLOCK標誌。
-
記錄鎖==位元組範圍鎖:當一個程式讀或修改檔案某部分時,可以阻止其他程式修改同一檔案區。有些系統中檔案的最後狀態取決於寫該檔案的最後一個程式。
-
同一程式可對同一位元組範圍重複加鎖,新鎖換老鎖。可以測試另一個程式是否對某記錄加鎖。
-
鎖是與程式、檔案兩者相關聯的。fork出的子程式不繼承父程式對檔案的鎖【避免父子同時寫一個檔案】。exec新程式繼承原程式的鎖。
-
某些unix提供系統呼叫跟蹤特性。
-
STREAM:構造核心裝置驅動程式和網路協議包的一種通用方法。
-
IO多路轉接【兩個描述符】:執行阻塞read,阻塞是對整個程式阻塞,如果多個通路【一般是無限迴圈讀、寫】想要相互不影響,就得fork多個程式,每個程式處理各自的檔案描述符。用非阻塞read輪詢描述符消耗cpu。
-
IO多路轉接思想:構造一張描述符表,呼叫一個函式,直到表中描述符中的一個已經準備好IO時,該函式返回,告訴程式哪些描述符可以IO。主要用於終端IO和網路IO。select(0, NULL, NULL, NULL, &tv)相當於sleep了,精確到微秒。
-
非同步IO:基本思想,告訴核心,當一個描述符已準備好可以進行IO時,用一個訊號通知它【它指應用程式】。系統V非同步IO調ioctl設定訊號處理,只對STREAMS裝置和STREAMS管道起作用。 BSD非同步IO設定訊號SIGIO處理程式,調fcntl設定O_ASYNC檔案為非同步IO。只對終端和網路描述符有效。
-
儲存對映IO:【將一個給定檔案對映到一個儲存區域】unsigned char* mmapBuf = (unsigned char)mmap(NULL【區域起始地址】, fileSize, PROT_READ【對映區可讀】, MAP_SHARED ,fd【被對映檔案】, 0【對映位元組在檔案中起始偏移量】) munmap((char)mmapBuf, fileSize)【解除對映】 msync沖洗到磁碟
-
IPC【InterProcess Communication】:各種管道、訊息佇列、訊號量、共享儲存、套接字、STREAMS【僅後兩種支援不同主機程式間通訊】
-
管道:半雙工【資料只能在一個方向上流動】;只能在公共祖先的程式間使用,通常fork後父子間使用。int pipe(int filedes[2]) fork後f[0]<-【核心自動?】-f[1] 有兩份,各關閉一個
-
sh -c cmdstring表示shell將擴充套件字串中的特殊字元【*.c】。
-
${PAGE:-more}如果PAGE已定義,使用,否則用more。
-
對管道標準IO預設全緩衝。
-
通過FIFO【命名管道】不相關的程式也能交換資料。int mkfifo(pathname, mode_t mode)類似於建立普通檔案。
-
建立IPC結構:msgget semget shmget 要指定一個鍵key_t。 ftok可由一個路徑名和專案ID產生一個鍵key_t ftok(path, id)
-
msgctl semctl shmctl修改uid、gid、mode 三種IPC都有內建限制,可通過配置核心修改。 ipcs檢視 ipcrm刪除
-
msgrcv可以是非先進先出
-
訊號量的值代表對應資源是否可以使用。semop(_ID, buf[]【陣列中操作要麼都執行,要麼都不執行】, 1)表示等待訊號量、釋放資源、獲取資源。semctl取訊號量資訊、設定訊號量資訊。
-
使用訊號量【實際上是同步原語而不是IPC】,先建立一個包含一個成員的訊號量集合,訊號量值賦初值1.分配資源時sem_op為-1呼叫semop,釋放資源sem_op為1呼叫semop。每次設定SEM_UNDO,以處理程式終止還有未釋放資源的情況。
-
shmget既可以建立,也可以引用已有的【msgget一樣】。 shmctl IPC_RMID減少引用數,不真正刪除。shmid和pickey不一樣,shmget返回值是shmid 。shmdt脫接不刪除,引用數減一。
-
套接字用於不同計算機上的程式相互通訊,其它程式執行位置透明。可以採用許多網路協議,TCP/IP常見。
-
建立一個套接字int socket(int domain【例如ipv4internet網域】, int type, int protocol)返回套接字檔案描述符。
-
int shutdown(int sockfd, int how)禁止套接字上的輸入輸出。uint32_t htonl(uint32_t hostint32)等進行處理器位元組序和網路位元組序的轉換。
-
inet_pton( AF_INET, host.c_str(), &m_addr.sin_addr)將文字字串轉換成網路位元組序的二進位制地址
-
poll select函式能檢查檔案描述符的狀態,用來決定是否對檔案描述符執行某種操作。
-
setsockopt(_sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len)
-
int fattach(int fileds, const char* path)使STREAMS管道和檔案系統中的一個名字關聯。
-
unix域套接字用於同一機器上程式間通訊。int ssocketpair(int domain, int type, int protocol, int sockfd[2])
-
終端IO:函式tcgetattr tcsetattr 終端IO控制函式大多tc開頭
-
很多資料庫實現都採用兩個檔案:索引檔案和資料檔案。
本文幫你在 Unix 下玩轉 C 語言
相關文章
- C 語言程式設計(unix) (轉)程式設計
- Unix C語言值得注意的地方(轉)C語言
- 輕鬆玩轉51微控制器C語言pdfC語言
- Linux下C語言程式設計(轉)LinuxC語言程式設計
- Unix下設計動態庫的方法《精通Unix下C語言程式設計與專案實踐》(一)薦C語言程式設計
- c語言 5.9.2下載C語言
- 掌握這幾種開發語言,讓你玩轉人工智慧人工智慧
- C++語言概述 (轉)C++
- 幫你提升 Python 的 27 種程式語言Python
- Linux下C語言程式設計簡介(轉)LinuxC語言程式設計
- c語言也能幹大事,讓你的c語言無所不能!!!!C語言
- 在Unix下用C編寫curses程式的一些常用模組(轉)
- 用 C 語言寫一個簡單的 Unix Shell(1)
- 用 C 語言寫一個簡單的 Unix Shell(2)
- C語言---整型字串轉換C語言字串
- c語言函式庫(轉)C語言函式
- C語言的角落——這些C語言不常用的特性你知道嗎?C語言
- linux下傳送email的c語言程式碼(轉)LinuxAIC語言
- SCO-UNIX在vmware下的安裝(轉)
- Java 生成本文檔案的時候,Dos格式轉成Unix格式Java
- Linux下C語言程式設計基礎知識(轉)LinuxC語言程式設計
- C語言 C語言野指標C語言指標
- C語言---“C語言 誰與爭鋒?”C語言
- 【C語言】聊聊輾轉相除法C語言
- C語言動態呼叫庫(轉)C語言
- C語言連線Oracle (轉載)C語言Oracle
- c語言字串,數字轉換C語言字串
- C 語言常見問題(轉)
- 在Linux系統下安裝Perl指令碼語言(轉)Linux指令碼
- 這些手機幫你玩轉自拍 當朋友圈明星
- 用C語言在Linux系統下建立守護程式(Daemon)C語言Linux
- 一套幫助你理解 C 語言的測試題
- C語言新手最常見的問題!你在這裡跌倒過嗎?C語言
- 不同裝置如何統一語言程式設計平臺高效開發?本文為你揭秘程式設計
- 在LoadRunner中轉換字串大小寫的C語言函式字串C語言函式
- Java語言和C++語言的差異 (轉)JavaC++
- ARM下C語言棧幀機制C語言
- 讓你又能嗨、又想翻的C語言!C語言