“Linux程式設計”小結(程式間通訊)
最近,藉著機會把《Linux程式設計(第4版)》這本書整本過了一遍。針對該書的主要知識要點, 自己做了總結和適當的補充,同時也標明瞭書中的一些錯誤
知識點
/proc
(P107)- Linux提供了一個特殊的檔案系統
procfs
,其以/proc
目錄的形式展現。該目錄中包含了許多特殊檔案用來對驅動程式和核心資訊進行更高層次的訪問。 cat /proc/cpuinfo
檢視cpu資訊cat /proc/sys/fs/file-max
檢視系統能同時使開啟的檔案總數,cat /proc/sys/fs/file-nr
可檢視具體的詳細資訊cat /proc/net/sockstat
獲取網路套接字資訊ls /proc/193/
檢視程式資訊(PID為193),od -c /proc/193/cmdline
檢視啟動該程式的命令- 在許可權允許的範圍內也可對部分內容進行修改(如可開啟檔案總數、網路核心引數等),但該修改在系統重啟後便會失效
- 原書109頁表述的“程式號在1~32000的數字,這是錯誤的!,具體值可通過
cat /proc/sys/kernel/pid_max
檢視,且就算在32位的系統下,PID的取值範圍應該是0~32767
(short int型別), 0用於idle程式, 1用於init程式或systemd程式
- Linux提供了一個特殊的檔案系統
- 檔案鎖定(P222)
- 可以鎖定整個檔案,也可鎖定檔案的一部分
- Linux通常會在
/var/spool
目錄下建立一個鎖檔案 - 鎖檔案是建議鎖,不是強制鎖
- 檔案中每個位元組在任意時刻只能擁有一種型別的鎖,即共享鎖(
F_RDLCK
,讀鎖)、獨佔鎖(F_WRLCK
,寫鎖)或解鎖(F_UNLCK
) - 檔案鎖的使用,很多時候相當於一個二進位制訊號量的使用
fcntl.h
中的open()
, 也可通過unistd.h
中的lockf()
進行設定- 預防死鎖
fcntl系統呼叫
(P110)- 其對底層檔案描述符提供了很多的操作方式
- 複製、獲取和設定檔案描述符標誌,獲取檔案狀態標誌,管理建議性檔案鎖
#include <fcntl.h>
mmap函式
(P111)- 即記憶體對映,其可以建立一段被兩個或多個程式讀寫的記憶體,允許程式間共享記憶體(Linux核心2.0版本開始包含該功能)
- mmap建立一個指向一段記憶體區域的指標,該記憶體區域的指標與可以通過一個開啟的檔案描述符訪問的檔案的內容關聯。
# include <sys/mman.h>
,mmap, msync, munmap
- 這是一種記憶體共享機制,還有另外一種System V共享記憶體的方式!
資源和限制(P139)
sys/resource.h
中包括對程式長度、執行優先順序和檔案資源等方面限制進行查詢和設定的函式limits.h
中定義了許多代表作業系統方面限制的顯示常量,如NAME_MAX
,CHAR_BIT
,CHAR_MAX
,INT_MAX
- 也可通過shell內建
ulimit
命令為某一特定shell中執行的程式設定限制 - 通過
/proc
,/etc/security/limits.conf
等方式進行設定 nice
可修改程式的執行優先順序
dbm資料庫(P237)
- dbm資料庫適合於儲存相對比較靜態的索引化資料,其也可以看做是一個索引化的檔案儲存系統
locate
和updatedb
也使用到一個系統資料庫(但和dbm有些不同)
程式和訊號(P388)
- UNIX中的定義“一個其中執行著一個或多個執行緒的地址空間和這些執行緒所需要的系統資源”
- 程式是系統資源分配的最小單位,執行緒是系統排程的最小單位, 執行緒是程式中的一個執行路徑
- 正在執行的程式由程式程式碼、資料、變數、開啟的檔案和環境組成
- 程式被啟動後,系統會按順序選擇一個未被使用的數字作為其PID
- 程式狀態程式碼(STAT),如
s
表示程式是會話期首程式 (P391) - 程式表就是一個資料結構,它會把載入到記憶體中所有程式的有關資訊儲存在一個表中
ps -ef
- 程式根據
nice
值來決定其優先順序,預設為0, 隨著其不間斷的執行,其值會不斷變化(往往降低) system()
是通過shell來啟動要執行的程式exec
系列函式,是通過替換程式映像來啟動新程式(把當前程式替換為一個新程式,原來的程式就不存在了),但PID, PPID和nice值和以前完全一樣。實質就是“執行中的程式開始執行exec呼叫中指定的可執行檔案中的程式碼” (P398)sys/wait.h
,sys/types.h
,unistd.h
,fork()
,wait()
,waitpid()
- 殭屍程式:子程式雖然不再執行,但其仍然存在於系統中,因為它的退出碼還需要儲存,已備父程式今後的wait呼叫使用。同時它將成為一個死(defunct)程式或殭屍(zombie)程式
- 核心轉儲檔案core,是程式在記憶體中的映象,其對除錯很有幫助
- 新程式中應該使用
sigaction
函式(很好的支援訊號集),少用signal
(P413) SIGKILL
是不可捕獲的fork()
函式的返回值可理解為指向當前程式的子程式連結串列(第一個號)
POSIX執行緒(P416)
- 準確定義:“執行緒是一個程式內部的一個控制序列”
- 新的執行緒有自己的棧,但與它的建立者共享全域性變數、檔案描述符、訊號處理函式、當前目錄狀態
- 執行緒庫使用“本地POSIX執行緒庫”(Native POSIX Thread Library, 即NPTL)
- 可重入歷程(程式碼被呼叫多次仍能正常工作,呼叫可以來自不同的執行緒,也可以是某種形式的巢狀呼叫)
- 編寫多執行緒程式時,需要動過定義
_REENTRANT
來高速編譯器我們需要可重入功能,且其定義必須位於#include
之前- 它會對部分函式重新定義他們的可安全重入版本,如
gethostbyname
將變為gethostbyname_r
stdio.h
中原來以巨集的形式實現的一些函式將變成可安全重入的函式errno.h
中定義的變數errno將成為一個函式呼叫,即以執行緒安全的方式來獲取真正的errno- 如編譯命令
cc -D_REENTRANT thread1.c -o thread1 -lpthread
- 它會對部分函式重新定義他們的可安全重入版本,如
pthread_creat
,pthread_join
,pthread_exit
- 同步(P423)
- 訊號量 (二進位制訊號量、計數訊號量),
#include <semaphore.h>
,sem_init
,sem_wait
(訊號量值-1),sem_post
(訊號量值+1),sem_destory
- 互斥量(互斥訪問),
#include <pthread.h>
,pthread_mutex_init
,pthread_mutex_lock
,pthread_mutex_unlock
,pthread_mutex_destroy
- 訊號量 (二進位制訊號量、計數訊號量),
- 執行緒的屬性
- 脫離執行緒(detach thread),通過修改執行緒的屬性或呼叫
pthread_detach
的方式來建立 pthread_attr_init
,pthread_attr_setdetachstate
,pthread_attr_getdetachstate
等- 取消執行緒
pthread_cancel
- 脫離執行緒(detach thread),通過修改執行緒的屬性或呼叫
程式間的通訊
管道 (P443)
- popen呼叫
stdio.h
中的FILE *popen(const char *command, const char *type)
,int pclose(FILE *stream)
- popen呼叫執行的一個程式時,首先啟動Shell,即系統中的sh命令,再將command字串作為一個引數傳遞個它,即每個popen將多啟動兩個程式!
pipe呼叫
unistd.h
中的int pipe(int pipefd[2])
,int pipe2(int pipefd[2], int flags);
- 寫到
pipefd[1]
中的所有資料都可以從pipefd[0]
中讀回來 - 如果在原先的程式中建立一個管道,然後再呼叫fork建立新的程式,即可通過管道在兩個程式之間傳遞資料!
dup呼叫
unistd.h
中int dup(int oldfd)
,int dup2(int oldfd, int newfd)
,int dup3(int oldfd, int newfd, int flags);
- 可把管道用作標準輸入和標準輸出
- 命名管道(有名管道)FIFO (P456)
- 可在不相關的程式之間交換資料
- named pipe 是一種特殊的檔案型別, 在檔案系統中以檔名的方式存在
mknod filename p
或者mkfifo filename p
可建立一個FIFO檔案- 在程式中可使用
#include <sys/types.h>
,#include <sys/stat.h>
中int mkfifo(const char *pathname, mode_t mode)
或者int mknod(const char *path, mode_t mode, dev_t dev)
- 同pipe建立的管道不同,FIFO以檔名的方式存在,在進行讀寫之前需要必須先
open
開啟
- popen呼叫
- 訊號量(P489)
- 這個訊號量函式比執行緒中的訊號量函式更常用!
- 用於管理對資源的訪問,它是一個特殊的變數,只能對它進行等待(wait)和傳送訊號(signal)操作
- PV操作:P用於等待;V用於傳送訊號
- 假設有一個訊號量sv, 則
P(sv)
,V(sv)
的意思? (P489) #include <sys/sem.h>
,semctl()
用於直接控制訊號量的資訊,semget()
建立一個新訊號量或者獲取一個已有的訊號量,semop()
用於改變訊號量的值- 訊號量都會對應到一個
key_t
(應用程式提供,有效地為訊號量命名)
- 共享記憶體(P496)
- 用於程式之間高效的共享資料,允許兩個不相關的程式訪問同一個邏輯單元
#include <sys/shm.h>
中shmget
建立或者獲取一個已有的,shmat
(第一次建立共享記憶體段時,其不能被任何程式訪問,要想啟動對該共享記憶體的訪問,必須將其連線到一個程式的地址空間中,shmat成功則返回共享記憶體第一個位元組的指標),shmdt
將共享記憶體從當前程式中分離- 共享記憶體會對應到一個
key_t
(應用程式提供,有效地為共享記憶體命名) mmap
也是實現記憶體共享的一種方式
- 套接字(P513)
- 本地套接字的名字是Linux檔案系統中的檔名,一般放在
/tmp
或/usr/tmp
目錄中,AF_UNIX
- 通過
socket(AF_UNIX, SOCK_STREAM, 0)
(UNIX檔案系統域)建立的本地套接字會在當前目錄下(預設)以檔案的形式存在,ls -lF socketname
檢視
- 通過
- 網路套接字,
AF_INET
,AF_INET6
等- 流套接字
SOCK_STREAM
, 資料包套接字SOCK_DGRAM
- 流套接字
- 套接字的特性由3個屬性確定:域(domain)、型別(type)、協議(protocol), 地址格式隨域(又名協議族, protocol family)
- 主機位元組序、網路位元組序:對於一個數字,高位(數字的位)在前(低地址空間)的是big endian, 低位在(低地址空間)前的是little endian, x86是little endian 記憶圖
- 因特網守護程式 (xinetd/inetd):UNIX以超級伺服器的方式來提供多項網路服務,而特定的網路服務往往在需要的時候才會啟動!
setsockopt()
可用來控制套接字的行為select()系統呼叫
允許程式同時在多個底層檔案描述符或套接字上等待輸入或處處活動的的到來;其可用於測試檔案描述符集,但每次都得遍歷全部的,通過其可同時處理多個客戶端而無需再依賴子程式了- IO多路複用機制:
select
,poll
,epoll
之間的區別 - 關於同步、非同步與阻塞、非阻塞的理解
- 本地套接字的名字是Linux檔案系統中的檔名,一般放在
- 訊號
- signal
- 檔案
- Linux將一切事物看做檔案
相關文章
- linux程式間通訊(IPC)小結Linux
- linux程式間通訊-----訊號總結Linux
- Linux環境程式設計程式間通訊機制理解Linux程式設計
- Linux系統程式設計之程式間通訊方式:訊息佇列Linux程式設計佇列
- Linux系統程式設計之程式間通訊方式:管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:管道(一)Linux程式設計
- linux環境程式設計(2): 使用pipe完成程式間通訊Linux程式設計
- Linux系統程式設計(11)——程式間通訊之有名管道Linux程式設計
- Linux程式間通訊Linux
- 程式間通訊——LINUXLinux
- Linux系統程式設計之程式間通訊方式:命名管道(二)Linux程式設計
- Linux系統程式設計之程式間通訊方式:命名管道(一)Linux程式設計
- linux環境程式設計(3): 使用POSIX IPC完成程式間通訊Linux程式設計
- linux程式間通訊-----管道總結例項Linux
- Linux程式間通訊-eventfdLinux
- Linux程式間通訊1Linux
- Linux程式間通訊2Linux
- UNIX網路程式設計 卷2:程式間通訊程式設計
- 什麼是程式間通訊?Linux程式間通訊有幾種方式?Linux
- 程式間通訊是什麼?Linux程式間通訊有幾種方式?Linux
- linux 程式間通訊之FIFOLinux
- Linux 的程式間通訊:管道Linux
- linux 程式間通訊之管道Linux
- Linux程式之間如何通訊?Linux
- Linux程式間通訊——使用訊號量Linux
- 程式間通訊
- LLinux系統程式設計(10)——程式間通訊之管道Linux程式設計
- linux程式間通訊--管道(PIPE & FIFO)Linux
- Linux程式間通訊②:有名管道FIFOLinux
- Linux系統程式設計之程式間通訊方式:共享記憶體例項演示Linux程式設計記憶體
- linux程式間通訊-----System V訊息佇列總結例項Linux佇列
- PHP程式間通訊PHP
- 程式間的通訊
- 程式間通訊(Socket)
- 程式間通訊 --IPC
- windows程式間通訊Windows
- 網路通訊程式設計程式設計
- Linux 程式間通訊之System V 訊號量Linux