Linux進程通信方式:
(1)管道(pipe)和命名管道(FIFO)
(2)信號
(3)消息隊列
(4)共享內存
(5)信號量
(6)套接字(socket)
一、管道通信
管道是單向的、先進先出、無結構的、固定大小的字節流,把一個進程的標準輸出同另一個進程的標準輸入連在一起。
管道通信主要是用於不同進程之間進行通信。
1、創建管道
int pipe (int fd[2])
fd[0]用於讀取管道,fd[1]用於寫入管道
創建一個管道後產生一個新的進程,調用成功:返回0,調用失敗:返回-1
一個簡單的程序:
- #include<unistd.h>
- #include<errno.h>
- #include<stdio.h>
- #include<stdlib.h>
- int main()
- {
- int pipe_fd[2];
- if(pipe(pipe_fd)<0)
- {
- printf("pipe create error/n");
- return -1;
- }
- else
- {
- printf(:pipe create success/n");
- }
- close(pipe_fd[0]);
- close(pipe_fd[1]);
- }
實際上,通常先創建一個管道,再通過fork函數創建一個子進程。
管道讀寫注意事項
(1)可通過打開兩個管道來創建一個雙向的管道。
(2)必須在系統調用fork()中調用pipe(),否則子進程不會繼承文件描述符。
(3)使用半雙工管道時,任何關聯的進程都必須共享一個相關的祖先進程。(管道存在於內核中,其他進程無法尋址它)
2、標準流管道
(1)、接口函數popen()創建;
返回值:若成功,返回一個新的文件流;
若無法創建進程或管道,返回NULL。
(2)、接口函數pclose()關閉;
返回值:返回系統調用的wait4()的狀態;
如果stream無效,或wait4()調用失敗,返回-1。
(3)、FILE *popen (char *command, char *type)………………*type:"r"或"w"
int pclose(FILE *stream)
3、有名管道(FIFO)
(1)命名管道是在文件系統中作爲一個特殊設備文件而存在;
(2)不同祖先進程之間可以通過管道共享數據;
(3)當共享管道的進程執行完所有的I/O操作以後,命名管道將繼續保存在文件系統中以便以後使用。
命名管道的創建
#include<sys/types.h>
#include<sysy/stat.h>
int mkfifo(const char *pathname, mode_t mode);
返回:若成功0,失敗-1。
一旦mkfifo創建了一個FIFO,就可用open、close、read、write
FIFO相關出錯信息
EACCES 無存取權限
EEXIST 指令文件不存在
ENAMETOOLONG 路徑名太長
ENOENT 包含的目錄不存在
ENOSPC 文件系統剩餘空間不足
ENOTDIR 文件路徑無效
EROFS 指定文件存在於只讀文件系統中
二、信號通信
信號是軟中斷,用於在一個或多個進程之間傳遞異步信號
(1)按下某些終端鍵,產生信號;
(2)硬件異常產生信號:如除數爲0,無效存儲訪問等;
(3)進程用kill函數將信號發送給另一個進程或進程組;
接收、發送的進程所有者相同,或盡頭信號的進程所有者爲超級用戶。
(4)用戶可用kill命令將信號發送給其他進程;
(5)檢測到某種軟件條件已經發生,並將其通知有關進程時產生信號。
主要的信號源:
(1)異常 進程運行過程中出現異常
(2)其他進程 一個進程向另一個或組進程發送信號
(3)終端中斷: ctrl+c ctrl+/ 等
(4)作業控制:前臺、後臺進程管理(狀態轉換等)
(5)分配額:CPU超時,文件大小超限
(6)通知:通知進程事件發生(I/O就緒)
(7)報警:計時器到期
Linux中的信號(30個以上)