1. 管道,有名管道和无名管道。
1.1 无名管道主要用于父子进程或者兄弟关系的进程间的通信。
通过pipe
创建无名管道
#include<stdio.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#define E_MSG(str, value) do{perror(str); return (value);}while(0)
int main(void){
int fd[2];
char buf[128];
char *msg = "hello my pipe test program\n";
//创建管道,fd[0]: read; fd[1]: write
int mypipe = pipe(fd);
if(mypipe == -1) E_MSG("pipe", -1);
pid_t pid = fork();
if(pid == -1) E_MSG("fork", -1);
if(pid == 0){
close(fd[1]); //关闭管道的写端
//从管道读取数据到buf中
//如果管道里没有数据,则阻塞等待
int r = read(fd[0], buf, 128);
write(1, buf, r); //向标准输出打印
close(fd[0]); //关闭读端
exit(0);
}
else {
close(fd[0]);
//开始写入数据
write(fd[1], msg, strlen(msg));
close(fd[1]); //关闭写端
wait(NULL); //等待子进程结束
}
return 0;
}
1.2. 有名管道,这是一种类型的文件,内容始终为0,只是起到进程间通信的桥梁作用。
可以通过mkfifo
创建有名管道
创建管道:
#include<stdio.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/stat.h>
#define E_MSG(str, value) do{perror(str); return (value);}while(0)
int main(int argc, char *argv[]){
int ff = mkfifo(argv[1], 0644);
if(ff == -1) E_MSG("mkfifo", -1);
printf("Create %s done\n", argv[1]);
return 0;
}
向管道写数据:
#include<stdio.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#define E_MSG(str, value) do{perror(str); return (value);}while(0)
int main(int argc, char *argv[]){
char *msg = "pipe test...\n";
int fd = open(argv[1], O_WRONLY);
if(fd == -1) E_MSG("open", -1);
write(fd, msg, strlen(msg));
close(fd);
return 0;
}
从管道读数据
#include<stdio.h>
#include<string.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#define E_MSG(str, value) do{perror(str); return (value);}while(0)
int main(int argc, char *argv[]){
char buf[128];
int fd = open(argv[1], O_RDONLY);
if(fd == -1) E_MSG("open", -1);
int r = read(fd, buf, 128);
write(1, buf, r);
close(fd);
return 0;
}
测试:
zhongjun@eclipse:~/projects$ gcc pipe.c -o pipe
zhongjun@eclipse:~/projects$ gcc pa.c -o pa
zhongjun@eclipse:~/projects$ gcc pb.c -o pb
zhongjun@eclipse:~/projects$ ./pipe ss
Create ss done
zhongjun@eclipse:~/projects$ ./pa ss
zhongjun@eclipse:~/projects$
zhongjun@eclipse:~/projects$ ./pb ss
pipe test...