1. 進程間通信方式介紹
這篇文章介紹linux下進程的間的通信方式,常用的方式如下:
1. socket—網絡通信 2. 管道---無名管道—命名管道---文件--FIFO 3. 消息隊列 4. 共享內存 5. 信號量集 6. 信號—signal捕獲信號---kill命令發送信號 int kill(pid_t pid, int sig);
2. 標準流管道
標準流管道像文件操作有標準io流一樣,管道也支持文件流模式。用來創建連接到另一進程的管道popen和pclose。
函數原型:
#include FILE* popen(const char* command, const char* open_mode); int pclose(FILE* fp);
popen用于啟動進程,用法含義與fopen類似,第二個參數填權限,支持填"r"和"w"。
pclose用于關閉進程,釋放資源。

popen啟動進程之后可以直接與啟動的進程間通信,比較方便。
**示例代碼: **從標準管道流中讀取 打印/etc/profile的內容:
#include #include int main() { FILE *file=NULL; size_t len=0; char buff[1024+1]; file=popen("cat /etc/profile","r"); //執行cat /etc/profile命令,讀方式。 if(file!=NULL) { len=fread(buff,1,1024,file); //讀數據 buff[len]='\0'; printf("len=%d\n %s\n",len,buff); } pclose(file); //等待線程結束。 return 0; }
3. 無名管道
無名管道用于有親戚關系的進程間通信。 比如: 兄弟進程、父子進程等。
#include int pipe(int fds[2]);
pipe函數用于創建一個無名管道,如果成功,fds[0]就存放可讀的文件描述符,fds[1]就存放可寫文件描述符。
返回值: 0表示成功,-1表示失敗。
無名管道的特點:
只能在親緣關系進程間通信(父子或兄弟)
半雙工(固定的讀端和固定的寫端)
虛擬管道文件是一個存在內存的特殊文件,可以用read、write函數進行操作。
這里說的管道,就像一條水管,有兩個端口,一端進水,另一端出水。管道也有兩個端口,分別是讀端和寫端,進水可看成數據從寫端被寫入,出水可看數據從讀端被讀出。在程序里分別就對應了read和write函數。
示例代碼:
#include #include #include int main(int argc,char **argv) { int fds[2]; /*1. 創建無名管道:得到管道讀寫文件描述符 fds[0]和讀端相對應, fds[1]和寫端相對應*/ pipe(fds); /*2. 創建子進程*/ pid_t pid; pid=fork(); if(pid==0) //子進程 { char buff[100+1]; int cnt; //從管道的讀端讀取數據 cnt=read(fds[0],buff,100); //帶阻塞功能 buff[cnt]='\0'; printf("子進程收到的數據:%d,%s\n",cnt,buff); } else //父進程 { char buff[]="1234567890"; //向管道的寫端寫數據 write(fds[1],buff,strlen(buff)); //等待子進程結束 wait(NULL); printf("父進程正常結束.\n"); } return 0; }
4. 命名管道
無名管道只能在親緣關系的進程間通信大大限制了管道的使用,有名管道突破了這個限制,通過指定路徑名的形式實現不相關進程間的通信,因為命名管道通信使用的管道是一個實體文件,在磁盤上的存在的,而無名管道是存在內存中的虛擬文件,其他進程無法訪問,導致沒有關聯的進程無法進行通信。
4.1 在命令行如何創建管道文件?
[wbyq@wbyq test]$ mkfifo test.fifo [wbyq@wbyq test]$ ls test.fifo [wbyq@wbyq test]$ ls -l 總用量 0 prw-rw-r--. 1 wbyq wbyq 0 10月 15 15:29 test.fifo
4.2 在命令行演示兩個相關的進程通過進行管道文件進行通信
4.3 創建fifo文件的函數
1. 創建FIFO文件 #include #include int mkfifo(const char *pathname, mode_t mode); 參數: pathname:創建的FIFO文件的全路徑名; mode:文件訪問權限,比如0666。 返回值:如果創建成功,則返回0,否則-1。 2. 刪除FIFO文件 #include int unlink(const char *pathname); 3. 用命令創建和刪除FIFO文件 用命令mkfifo創建。 用命令unlink刪除。
4.4 創建寫端: FIFO
#include #include #include #include #include #include int main(int argc,char **argv) { if(argc!=2) { printf("./a.out \n"); return 0; } int fd=open(argv[1],O_WRONLY); if(fd<0) { printf("%s 文件打開失敗.\n",argv[1]); return 0; } char buff[]="1234567890"; write(fd,buff,strlen(buff)); close(fd); return 0; } 示例代碼: 進程B負責讀數據 #include #include #include #include #include #include int main(int argc,char **argv) { if(argc!=2) { printf("./a.out \n"); return 0; } int fd=open(argv[1],O_RDONLY); if(fd<0) { printf("%s 文件打開失敗.\n",argv[1]); return 0; } char buff[100+1]; int cnt; cnt=read(fd,buff,100); buff[cnt]='\0'; printf("buff=%s\n",buff); close(fd); return 0; }
4.5 創建讀端: FIFO
在命令行演示兩個相關的進程通過進行管道文件進行通信.
代碼創建讀端,讀取數據:
#include #include #include #include #include #include int main(void) { int fd=0; int len=0; char buff[100]; fd=open("myfifo",O_RDONLY); len=read(fd,buff,100); buff[len]='\0'; printf("read: %s\n",buff); return 0; }
Linux 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。