通过管道进行通信
管道属于操作系统
int pipe(int filedes[2]);
成功返回 0, 失败返回-1
filedes[0]: 通过管道接收数据时使用的文件描述符,即管道出口
filedes[1]: 通过管道传输数据时使用的文件描述符,即管道入口
父进程调用该函数创建管道,同时获取对应的出入口文件描述符。为了与子进程通信,需要将入口或者出口中的文件描述符传给子进程,通过fork()
函数传递。
#define BUF_SIZE 30
int main(int argc, char *argv[]) {
int fds[2];
char str[] = "who are you?";
char buf[BUF_SIZE];
pid_t pid;
pipe(fds); //调用成功后,fds 会同时保存父子进程的 socket 文件描述符
pid = fork();
if (pid == 0) {
//子进程仅用输入路径
write(fds[1], str, sizeof(str));
} else {
//父进程仅用输出路径
read(fds[0], buf, BUF_SIZE);
puts(buf);
}
return 0;
}
父子进程都可是访问管道的 I/O 路径,倒是子进程仅用输入路径,父进程仅用输出路径。
通过管道进行进程间双向通信
#define BUF_SIZE 30
int main(int argc, char *argv[]) {
int fds[2];
char str1[] = "who are you?";
char str2[] = "thank you for your message";
char buf[BUF_SIZE];
pid_t pid;
pipe(fds);
pid = fork();
if (pid == 0) {
write(fds[1], str1, sizeof(str1));
sleep(2); //防止子进程把自己 write 的读取
read(fds[0], buf, BUF_SIZE);
printf("child proc output: %s \n", buf);
} else {
//接收子进程传过来的数据
read(fds[0], buf, BUF_SIZE);
printf("parent proc output: %s \n", buf);
//向子进程传输数据
write(fds[1], str2, sizeof(str2));
sleep(3);
}
return 0;
}
向管道传递数据时,先读的进程会把数据取走,数据进入管道后成为无主数据,哪个进程先调用read()
函数进行读取,就先获取到这个数据。
因此,可以创建 2 个管道进行通信
fds1 数据入口,write
fds0 数据出口,read
int main(int argc, char *argv[]) {
int fds1[2], fds2[2];
char str1[] = "who are you?";
char str2[] = "thank you for your message";
char buf[BUF_SIZE];
pid_t pid;
pipe(fds1);
pipe(fds2);
pid = fork();
if (pid == 0) {
write(fds1[1], str1, sizeof(str1));
read(fds2[0], buf, BUF_SIZE);
printf("child proc output: %s \n", buf);
} else {
read(fds1[0], buf, BUF_SIZE);
printf("parent proc output: %s \n", buf);
write(fds2[1], str2, sizeof(str2));
sleep(3);
}
return 0;
}