程序間通訊的方式簡單解析————管道
阿新 • • 發佈:2018-12-16
本人最近學習了程序間通訊,並看了一些博文,然後結合書籍根據自己的理解寫了這篇文章。
1. 管道
函式原型:經由引數fd返回兩個檔案描述符:fd[0]為讀,fd[1]為寫。fd[1]的輸出是fd[0]的輸入。
#include <unistd.h>
int pipe(int fd[2]);
侷限性:
(1)歷史上,它是半雙工的,某些系統提供全雙工管道,即其可移植性並不好。
(2)它只能在具有公共祖先的兩個程序間使用。
示例程式碼:
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
int main(){
int pipe_fd[2];
int ret = pipe(pipe_fd);//類似兩個檔案指標,針對管道中的讀(0)和寫(1)
if(ret == -1){
printf("建立管道失敗,錯誤碼是:%d,%d\n",error,strerror(error));
return 0;
}
pid_t pid = fork();//建立子程序
if(pid < 0){
printf("建立子程序錯誤\n");
return 0;
}
else if(pid == 0){ //子程序的操作
close(_pipe[0]); // 關閉讀通道
int i = 0;
char sendbuf[BUFSIZ];
while( i < 20){
scanf("%s", sendbuf);
write(pipe_fd[1], sendbuf, strlen(sendbuf));
sleep(2);
i++;
}
}
else { //進入父程序,從子程序讀取資料
close(pipe_fd[1]); //關閉寫通道
char recv[BUFSIZ];
while(1){
memset(recv, 0, sizeof(recv));
int length= read(pipe_fd[0], recv, sizeof(recv));
if(strstr(recv, "quit") != 0){
printf("退出程式\n");
exit(0);
}
printf("message:%s. length:%d.\n", recv, length);
}
if(waitpid(pid, NULL, 0) < 0){ //避免父程序與子程序衝突,讓子程序先執行
return 0;
}
}
return 0;
}
執行結果:
2. 命名管道(FIFO)
函式原型:
#include<sys/stat.h>
int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);
引數資訊:
(1)引數fd為檔案描述符。
(2)引數path為路徑名。
(3)mode引數指定檔案的訪問許可權位。
FIFO的用途:
(1)shell命令使用FIFO將資料從一條管道傳送到另一條時,無需建立中間臨時檔案。
(2)C/S應用程式中,FIFO用作匯聚點,在二者之間傳遞資料。
示例程式碼:fifo-read.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define _PATH_ "/tmp/file.fifo"
int main(){
int fd = open(_PATH_, O_RDONLY);//以只讀的許可權開啟檔案
if(fd < 0){
printf("開啟失敗\n");
return 0;
}
char recv[BUFSIZ];
while(1){
memset(recv, 0, sizeof(recv));//字串清零
int ret = read(fd, recv, sizeof(recv));
if(strstr(recv, "quit") != 0){ //判斷接收到的字元是否是quit
printf("退出程式\n");
exit(0);
}
printf("message:%-20s. length:%d\n", recv, ret);
}
close(fd);//關閉檔案
return 0;
}
執行結果:
fifo-write,c
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#define _PATH_ "/tmp/file.fifo"
int main(){
int ret = mkfifo(_PATH_, 0666);//建立管道檔案
if(ret == -1){
printf("建立管道失敗\n");
exit(0);
}
int fd = open(_PATH_, O_WRONLY);//以只寫的許可權開啟檔案
if(fd < 0){
printf("開啟失敗\n");
exit(0);
}
char buf[BUFSIZ];
while(1){
memset(buf, 0, strlen(buf));//字串清零
printf("please input the string:");
scanf("%s", buf);
int ret = write(fd, buf, strlen(buf));//寫資料
if(ret < 0){
printf("寫出錯\n");
break;
}
if(strstr(buf, "quit") != 0){
break;
}
}
close(fd);//關閉檔案
unlink(_PATH_);//刪除管道檔案
return 0;
}