匿名管道是用于在具有亲缘关系的进程(如父子进程)之间进行单向通信的简单方式。管道创建时包含两个文件描述符:一个用于读(读端),一个用于写(写端)。
#include
#include
#include
#include
#include
int main()
{
int pipefd[2]; // 用于保存管道文件描述符
pid_t cpid;
char buf;
if (pipe(pipefd) == -1)
{ // 创建管道
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork(); // 创建子进程
if (cpid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0)
{ // 子进程
close(pipefd[1]); // 关闭写端
while (read(pipefd[0], &buf, 1) > 0)
{
write(STDOUT_FILENO, &buf, 1); // 读取管道并输出到标准输出
}
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]); // 关闭读端
_exit(EXIT_SUCCESS);
}
else
{ // 父进程
close(pipefd[0]); // 关闭读端
const char *msg = "Hello from parent process!";
write(pipefd[1], msg, strlen(msg)); // 写入管道
close(pipefd[1]); // 关闭写端
wait(NULL); // 等待子进程结束
exit(EXIT_SUCCESS);
}
}
pipe(pipefd)
创建一个匿名管道,其中pipefd[0]
是读端,pipefd[1]
是写端。fork()
创建一个子进程。cpid
在子进程中为0,在父进程中为子进程ID。Hello from parent process!
命名管道(FIFO)是一种特殊的文件,可以用于无亲缘关系的进程之间进行双向通信。它通过在文件系统中创建一个命名管道文件进行通信。
首先,创建一个命名管道文件:
mkfifo /tmp/myfifo
然后,编写两个程序,一个用于写入数据,另一个用于读取数据。
#include
#include
#include
#include
#include
int main()
{
const char *fifo = "/tmp/myfifo";
int fd = open(fifo, O_WRONLY); // 打开命名管道的写端
if (fd == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
const char *msg = "Hello from writer process!";
write(fd, msg, strlen(msg)); // 写入数据到命名管道
close(fd); // 关闭管道
return 0;
}
#include
#include
#include
#include
#include
int main()
{
const char *fifo = "/tmp/myfifo";
char buf[128];
int fd = open(fifo, O_RDONLY); // 打开命名管道的读端
if (fd == -1)
{
perror("open");
exit(EXIT_FAILURE);
}
ssize_t numBytes = read(fd, buf, sizeof(buf)); // 从管道读取数据
if (numBytes > 0)
{
buf[numBytes] = '\0';
std::cout << "Received message: " << buf << std::endl; // 输出读取的数据
}
close(fd); // 关闭管道
return 0;
}
mkfifo
命令在文件系统中创建一个命名管道文件。mkfifo /tmp/myfifo
writer.cpp
和reader.cpp
:g++ writer.cpp -o writer
g++ reader.cpp -o reader
./reader
./writer
第一个终端(运行读取程序)输出:
Received message: Hello from writer process!