进程通信
Table of Contents
进程间通信,InterProcess Communication, IPC,是进程之间交换信息的途径。
管道⌗
管道是 UNIX 系统 IPC 的最古老的形式。有两种局限性:
- 历史上,它们是半双工的,为了最佳的可移植性,不能预先假定系统支持全双工管道。
- 管道只能在具有公共祖先的两个进程之间使用。通常,一个管道由一个进程创建,在进程调用 fork 之后,这个管道就能在父进程和子进程之间使用了。
#include <unistd.h>
int pipe(int fd[2]);
经由 fd 返回两个文件描述符:fd[0]
为读而打开,fd[1]
为写而打开。fd[1]
的输出是 fd[0]
的输入。
#include "apue.h"
int main()
{
int n;
int fd[2];
pid_t pid;
char line[MAXLINE];
if (pipe(fd) < 0)
err_sys("pipe error");
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid > 0) { // parent
close(fd[0]);
write(fd[1], "hello world\n", 12);
} else { // child
close(fd[1]);
n = read(fd[0], line, MAXLINE);
write(STDOUT_FILENO, line, n);
}
exit(0);
}
popen & pclose⌗
为了简化创建管道的过程,标准库提供了 popen 和 pclose 函数。
#include <stdio.h>
FILE *popen(const char *cmdstring, const char *type);
int pclose(FILE *fp);
如果 type 是 r
,则文件指针连接到 cmdstring 的标准输出;如果 type 是 w
,则文件指针连接到 cmdstring 的标准输入。
FIFO⌗
FIFO 有时候被称为命名管道,未命名的管道只能在两个相关的进程之间使用,而且这两个相关的进程还要有一个共同的创建了它们的祖先进程。但是,通过 FIFO,不相关的进程也能交换数据。
#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);