目录
例子1 父进程向子进程发送一条消息,子进程读取这条消息
例子2 mkfifo 函数创建一个命名管道
例子3 mkfifo 函数创建一个命名管道处理可能出现的错误
例子4 管道文件是否已存在
例子5 除了“文件已存在”进行处理
例子6 创建一个命名管道,并尝试打开它以进行读取
例子7 创建一个命名管道(FIFO),打开它用于读取数据,并循环读取来自管道的数据,直到程序被手动终止
例子8 持续写入特定消息到命名管道中直到达到指定次数后终止
例子9 打开一个已存在的命名管道(FIFO)以进行写操作
例子1 父进程向子进程发送一条消息,子进程读取这条消息
#include <stdio.h> // 包含标准输入输出函数库
#include <unistd.h> // 包含各种系统调用和基本的函数声明,如fork(), pipe(), read(), write()
#include <string.h> // 包含字符串处理函数库
#include <stdlib.h> // 包含标准库函数,如exit()
int main()
{
int fd[2]; // 用于存储管道的文件描述符,fd[0]用于读,fd[1]用于写
int pid; // 用于存储进程ID
char buf[128]; // 缓冲区,用于存储从管道读取的数据
// 创建管道
if(pipe(fd) == -1){
printf("create pipe failed\n");
return -1; // 管道创建失败时,打印错误信息并退出程序
}
pid = fork(); // 创建子进程
if(pid < 0){ // fork失败
printf("create child failed\n");
return -1; // 进程创建失败时,打印错误信息并退出程序
}
else if(pid > 0){ // 父进程执行的分支
sleep(3); // 父进程等待3秒,确保子进程准备好接收数据
printf("this is father\n");
close(fd[0]); // 父进程关闭管道的读端
write(fd[1], "hello from father", strlen("hello from father")); // 向管道写入数据
wait(); // 等待子进程结束
} else { // 子进程执行的分支
printf("this is child\n");
close(fd[1]); // 子进程关闭管道的写端
read(fd[0], buf, 128); // 从管道读取数据
printf("read from father: %s\n", buf); // 打印从父进程读取的数据
exit(0); // 子进程正常退出
}
return 0; // 主程序正常结束
}
例子2 mkfifo
函数创建一个命名管道
#include <sys/types.h> // 包含数据类型定义,如pid_t、mode_t
#include <sys/stat.h> // 包含文件状态定义,用于文件操作,如mkfifo
// 主函数入口
int main()
{
// 使用mkfifo系统调用创建一个名为"./file"的命名管道
// 参数 "./file" 是命名管道的路径和名称
// 参数 0600 是设置文件的权限,表示只有所有者有读写权限
// 0600 对应于八进制,实际权限是 -rw-------
mkfifo("./file", 0600);
return 0; // 返回0,正常结束程序
}
例子3 mkfifo
函数创建一个命名管道处理可能出现的错误
#include <sys/types.h> // 包含数据类型定义,如pid_t、mode_t
#include <sys/stat.h> // 包含文件状态定义,用于文件操作,如mkfifo
#include <stdio.h> // 包含标凈输入输出库函数
// 主函数入口
int main()
{
// 尝试创建一个名为"./file"的命名管道,设置权限为0600(只有所有者有读写权限)
int ret = mkfifo("./file", 0600);
// 判断mkfifo函数的返回值
if(ret == 0){ // 如果返回值为0,说明命名管道创建成功
printf("mkfifo success\n"); // 输出成功消息
}
if(ret == -1){ // 如果返回值为-1,说明命名管道创建失败
printf("mkfifo failure\n"); // 输出失败消息
perror("why"); // 使用perror输出错误原因,它会根据全局变量errno来描述错误详情
}
return 0; // 程序正常结束,返回0
}
例子4 管道文件是否已存在
#include <sys/types.h> // 包含数据类型定义,用于多种系统调用
#include <sys/stat.h> // 包含文件属性的定义,用于文件权限设置
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
// 主函数入口
int main()
{
// 尝试创建一个命名管道,路径为"./file",权限为0600(只有文件所有者有读写权限)
if((mkfifo("./file", 0600) == -1) && errno == EEXIST){ // 如果创建失败且错误号为EEXIST(文件已存在)
printf("mkfifo failure\n"); // 打印失败消息
perror("why"); // 使用perror输出错误原因
}
else{
if(errno == EEXIST){ // 如果创建管道时未进入第一个条件分支,但错误号仍然为EEXIST
printf("file exists\n"); // 打印文件已存在的消息
} else {
printf("mkfifo success\n"); // 否则打印成功创建管道的消息
}
}
return 0; // 程序正常结束
}
例子5 除了“文件已存在”进行处理
#include <sys/types.h> // 包含系统数据类型定义
#include <sys/stat.h> // 包含文件状态和权限定义
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
// 主函数入口
int main()
{
// 尝试创建一个命名管道,路径为"./file",权限为0600(只有文件所有者有读写权限)
if((mkfifo("./file", 0600) == -1) && errno != EEXIST){ // 如果创建失败且错误号不是EEXIST(文件已存在)
printf("mkfifo failure\n"); // 打印失败消息
perror("why"); // 使用perror输出具体的错误原因
}
// 如果创建失败但错误原因是文件已存在(EEXIST),则不执行任何操作,也不打印错误消息
return 0; // 程序正常结束
}
例子6 创建一个命名管道,并尝试打开它以进行读取
#include <sys/types.h> // 包含系统数据类型定义
#include <sys/stat.h> // 包含文件状态和权限定义
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
#include <fcntl.h> // 包含文件控制系统调用,如open
// 主函数入口
int main()
{
// 尝试创建一个名为"./file"的命名管道,设置权限为0600(只有文件所有者有读写权限)
if ((mkfifo("./file", 0600) == -1) && errno != EEXIST) { // 如果创建失败且错误号不是EEXIST(文件已存在)
printf("mkfifo failure\n"); // 打印失败消息
perror("why"); // 使用perror输出具体的错误原因
}
// 如果创建命名管道成功或错误原因是文件已存在,继续执行
// 打开刚创建的命名管道文件,以只读模式打开
int fd = open("./file", O_RDONLY);
if (fd == -1) { // 检查文件是否成功打开
perror("Open failed"); // 打开失败,输出错误信息
return -1; // 返回非零值表示程序异常结束
}
printf("open success\n"); // 打开成功,输出成功消息
// 实际使用中应该在这里进行读取操作,然后处理数据
// 不再使用文件时,应该关闭文件描述符
close(fd);
return 0; // 程序正常结束
}
例子7 创建一个命名管道(FIFO),打开它用于读取数据,并循环读取来自管道的数据,直到程序被手动终止
#include <sys/types.h> // 包含系统数据类型定义
#include <sys/stat.h> // 包含文件状态定义,用于文件操作,如mkfifo
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
#include <fcntl.h> // 包含文件控制系统调用,如open
int main()
{
char buf[30] = {0}; // 定义一个字符数组用于接收读取的数据,初始化所有元素为0
int nread = 0; // 用于存储read函数返回的实际读取字节数
// 尝试创建命名管道"./file",权限设置为0600(只有文件所有者有读写权限)
if ((mkfifo("./file", 0600) == -1) && errno != EEXIST) {
printf("mkfifo failure\n"); // 如果创建失败并且错误不是因为文件已存在,打印失败消息
perror("why"); // 使用perror输出错误的详细原因
return -1; // 创建失败,返回非零值表示程序异常结束
}
// 打开命名管道,只读模式
int fd = open("./file", O_RDONLY);
if (fd == -1) { // 检查文件是否成功打开
perror("Open failed"); // 打开失败,输出错误信息
return -1; // 返回非零值表示程序异常结束
}
printf("open success\n"); // 打开成功,输出成功消息
// 循环读取管道中的数据
while (1) {
nread = read(fd, buf, 30); // 从管道文件中读取最多30个字符到buf中
if (nread == -1) { // 检查读取是否成功
perror("Read failed"); // 读取失败,输出错误信息
close(fd); // 关闭文件描述符
return -1; // 返回非零值表示程序异常结束
}
printf("read %d bytes from fifo, context: %s\n", nread, buf);
if (nread == 0) { // 如果没有数据可读(读到EOF)
break; // 退出循环
}
}
close(fd); // 循环结束后,关闭文件描述符
return 0; // 程序正常结束
}
例子8 持续写入特定消息到命名管道中直到达到指定次数后终止
#include <sys/types.h> // 包含数据类型定义,如pid_t
#include <sys/stat.h> // 包含文件状态定义,用于文件操作,如mkfifo
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
#include <fcntl.h> // 包含文件控制系统调用,如open
#include <string.h> // 包含字符串处理函数库
#include <unistd.h> // 包含常用的系统调用,如sleep
int main()
{
int cnt = 0; // 用于计数,记录已写入消息的次数
char *str = "message from fifo"; // 定义要写入管道的消息
// 尝试以只写模式打开名为"./file"的FIFO
int fd = open("./file", O_WRONLY);
if (fd == -1) { // 检查文件是否成功打开
perror("Open error"); // 打开失败,输出错误信息
return -1; // 程序异常退出
}
printf("write open success\n"); // 打开成功,打印确认消息
// 循环写入数据到FIFO
while(1){
write(fd, str, strlen(str)); // 向FIFO写入字符串
sleep(1); // 每次写入后暂停1秒
cnt++; // 更新计数器
if(cnt == 5){
break; // 当写入5次后跳出循环
}
}
close(fd); // 关闭FIFO文件描述符
return 0; // 程序正常结束
}
例子9 打开一个已存在的命名管道(FIFO)以进行写操作
#include <sys/types.h> // 包含系统数据类型定义
#include <sys/stat.h> // 包含文件状态定义,用于文件操作,如mkfifo
#include <stdio.h> // 包含标准输入输出函数库
#include <errno.h> // 包含错误号定义,用于错误处理
#include <fcntl.h> // 包含文件控制系统调用,如open
int main()
{
// 尝试以只写模式打开名为 "./file" 的 FIFO
int fd = open("./file", O_WRONLY);
if (fd == -1) { // 检查文件是否成功打开
perror("Open error"); // 打开失败,输出错误信息
return -1; // 程序异常退出
}
printf("write open success\n"); // 打开成功,打印确认消息
// 此处应添加写操作,但当前示例仅演示打开操作
// 关闭文件描述符
close(fd);
return 0; // 程序正常结束
}