本篇文章給大家?guī)砹岁P于linux進程間通信的相關知識,其中包括管道、匿名管道、共享內存等相關問題,希望對大家有幫助。
·進程間通信:操作系統(tǒng)為系統(tǒng)提供的用于實現(xiàn)進程間通信的方式
? ? 進程之間是無法直接通信的,因為每個進程都有獨立的虛擬地址空間,訪問的都是自己的虛擬地址,因此進程具有獨立性,無法直接通信
? ? 根據通信場景的不同,因此提供了多種不同的通信方式
? ? 進程間通信方式種類:管道、共享內存、消息隊列、信號量
·管道
? ? 特性:半雙工通信–可以選擇方向的單向通信
? ? 本質:在內核中開辟一塊緩沖區(qū)(內核空間中的一塊內存)
? ? 原理:多個進程通過訪問同一塊內核中的緩沖區(qū)實現(xiàn)通信(復制緩沖區(qū)的操作句柄)
? ? 分類:匿名管道:緩沖區(qū)沒有標識符,只能用于具有親緣關系的進程間通信
?? ?? ? 命名管道:緩沖區(qū)具有標識符,可用于同一主機上任意的進程間通信
? ? linux下一切皆文件–所有東西都是當做文件一樣進行操作(包括管道),通過IO操作完成對管道的訪問
·匿名管道
? ?
? ? 返回值:成功返回0;失敗返回-1
? ? 特性:只能用于具有親緣關系的進程間通信
?? ?? ? 匿名管道沒有標識符,無法被其他進程找到,只能通過子進程復制父進程的方式獲取到操作句柄實現(xiàn)通信
? ? 讀寫特性:若管道中沒有數(shù)據,則read會阻塞
?? ?? ? 若管道中數(shù)據滿了,則write會阻塞
?? ?? ? 所有的管道的讀端被關閉,則繼續(xù)write則會觸發(fā)異常,導致進程崩潰退出
?? ?? ? 所有的管道的寫端被關閉,則繼續(xù)read則會讀完數(shù)據后返回0,不再阻塞
? ? 注:管道是半雙工通信,在通信時,一旦選定了?方向,應將不使用的那一端關閉。
· 命名管道:本質是 內核中的一塊緩沖區(qū),具有標識符,可以被其他進程找到,因此可用于同一主機上的任意進程間通信
? ? 命名管道的標識符就是一個可見于文件系統(tǒng)的管道類型文件
? ? 多個進程通過打開同一個管道文件,訪問同一塊內核中的緩沖區(qū)實現(xiàn)通信
? ? 命令操作:mkfifo? filename?創(chuàng)建一個命名管道文件
? ? 函數(shù)操作:int mkfifo(const char *pathname, mode_t mode);
?? ?? ? pathname:文件名稱;mode:創(chuàng)建權限
?? ?? ? 返回值:成功返回0;失敗返回-1
·總結:管道的本質:內核空間中的一塊緩沖區(qū)
? ? ?原理:多個進程通過訪問同一塊緩沖區(qū)實現(xiàn)數(shù)據傳輸
? ? ?分類:匿名管道、命名管道?
? ? ? ? ? ?匿名管道:只能用于具有親緣關系的進程間通信
? ? ? ? ? ?命名管道:可以用于同一主機上任意進程間通信
? ? ?特性:①半雙工通信–可以選擇方向的單向通信
?? ?? ? 提供字節(jié)流傳輸服務:有序的、可靠的、基于連接的一種流式傳輸
?? ?? ? 基于連接:所有讀端關閉則write異常;所有寫端關閉則read返回0
?? ?? ? ②自帶同步與互斥:
?? ??? ?? ? 同步:通過同一時間進程對臨界資源的唯一訪問實現(xiàn)訪問操作安全
?? ??? ?? ? 互斥:通過一些條件判斷讓進程對臨界資源的訪問更加合理有序
?? ??? ?? ? 互斥的體現(xiàn):對管道進行寫入操作的大小不超過PIPE_BUF-4096大小,則保證操作的原子性
?? ??? ?? ? 同步的體現(xiàn):管道沒有數(shù)據則read阻塞,管道數(shù)據寫滿則write阻塞
?? ?? ? ③生命周期隨進程:不人為干預情況下,所有打開管道的進程退出后,管道緩沖區(qū)被釋放
·共享內存:用于實現(xiàn)進程間的數(shù)據共享
? ? 本質:一塊物理內存
? ? 原理:開辟一塊物理內存空間,多個進程將同一塊映射到自己的虛擬地址空間,通過虛擬地址直接進行訪問,進而實現(xiàn)數(shù)據共享
? ? 特性:最快的進程間通信方式,生命周期隨內核
?? ?? ? 共享內存通過虛擬地址直接訪問物理內存,實現(xiàn)數(shù)據共享,相對于其他方式需要將數(shù)據拷貝到內核,使用時拷貝到用戶態(tài),少了兩次數(shù)據拷貝操作
? ? 注意事項:對共享內存的操作需要注意安全問題
? ? 操作流程:
?? ?? ? ①創(chuàng)建或打開共享內存
?? ?? ? ②將共享內存映射到進程的虛擬地址空間
?? ?? ? ③通過映射的虛擬地址進行各種內存操作
?? ?? ? ④解除映射關系
?? ?? ? ⑤刪除共享內存
?? ?? ? int shmget(key_t key, size_t size, int shmflg);
?? ??? ?? ? key:標識符(多個進程通過相同的標識符打開同一塊共享內存)
?? ??? ?? ? size:創(chuàng)建時所開辟的空間大小(以內存頁為單位)
?? ??? ?? ? shmflg:打開方式 +?創(chuàng)建權限–IPC_CREAT|IPC_EXCL|0664
?? ??? ?? ? 返回值: 成功返回一個非負整數(shù)–操作句柄;失敗返回-1
?? ?? ? void *shmat(int shmid, const void *shmaddr, int shmflg);
?? ??? ?? ? shmid:shmget返回的操作句柄
?? ??? ?? ? shmaddr:映射地址,通常設置為NULL
?? ??? ?? ? shmflg:映射成功后的訪問方式;SHM_RDONLY-只讀;0-讀寫
?? ??? ?? ? 返回值:成功則返回映射后的首地址;失敗返回(void *)-1
?? ?? ? int shmdt(const void *shmaddr);
?? ??? ?? ? shmaddr:映射后的首地址
?? ??? ?? ? 返回值:成功返回0;失敗返回-1
?? ?? ? int shmctl(int shmid, int cmd, struct shmid_ds *buf);
?? ??? ?? ? shmid:shmget返回的操作句柄
?? ??? ?? ? cmd:操作類型–IPC_RMID?標記共享內存為被銷毀
?? ??? ?? ? buf:對于IPC_RMID,成功返回0,失敗發(fā)返回-1
·消息隊列
? ? 本質:內核中的一個優(yōu)先級隊列,多個進程通過訪問同一個隊列,向隊列中添加或者獲取節(jié)點而實現(xiàn)進程間的數(shù)據塊傳輸
? ? 特性:自帶同步與互斥,生命周期隨內核
·信號量
? ? 本質:內核中的一個計數(shù)器 + pcb等待隊列
? ? 作用:用于實現(xiàn)進程間的同步與互斥,協(xié)調進程對臨界資源的訪問
? ? P操作:計數(shù)器-1,判斷若計數(shù)小于0則阻塞進程
? ? V操作:計數(shù)器+1,喚醒一個阻塞的進程
? ? 通過自身的計數(shù)器對資源進行計數(shù),通過計數(shù)判斷進程對資源的獲取是否合理,不合理則阻塞。等待產生一個資源之后,喚醒阻塞的進程
? ? 同步的實現(xiàn):通過計數(shù)器對資源進行計數(shù),在獲取資源之前進行P操作
? ? 互斥的實現(xiàn):計數(shù)器為1,表示資源只有一個,進程訪問資源之前進行P操作,訪問完畢后進行V操作
相關推薦:《Linux視頻教程》