有名管道----mkfifo函数的使用
有名管道
有名管道可以在任意两个进程之间通信,而无名管道只能在父子进程之间进行通信。此外,有名管道可以通过路径名来指出,并且在文件系统中可见。
管道的通信方式: 半双工。
mkfifo函数介绍
- 函数功能:创建有名管道。
- 函数原型:
int mkfifo(const char*filename,mode_t mode)
。
参数1(filename):是将要在文件系统中创建的一个专用文件。
参数2(mode):用来规定FIFO的读写权限。 - 函数返回值:成功返回0,失败返回-1。
- 函数所需头文件:
#include <sys/types.h>
,#include <sys/stat.h>
。
mkfifo函数使用
- 使用mkfifo创建一个有名管道,其中代码如下所示。
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>
#include <cstdio>
#include <iostream>
const char buf[] = "hello";
const int32_t bufSize = sizeof(buf);
const char str[] = "./myfifo";
int main()
{
//创建命名管道
int ret = mkfifo(str, S_IFIFO | 0666);
if (ret == -1)
{
std::cout << "Make fifo error\n";
return -1;
}
pid_t pid;
pid = fork();
if (pid > 0) {
int32_t fd = open(str, O_WRONLY);
if (write(fd, buf, bufSize) < 0) {
std::cout << "write error\n";
}
close(fd);
return 0;
}
sleep(1);
char readBuf[bufSize];
int32_t fd = open(str, O_RDONLY);
if (read(fd, readBuf, bufSize) < 0) {
std::cout << "read error\n";
}
else {
std::cout << buf << '\n';
}
close(fd);
return 0;
}
进行测试:
- 接着通过创建的管道实现无亲缘关系进程间通信,分别创建两个进程用来进行读写。
其中"read.cpp
"代码如下:
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
int main()
{
int fd = open("./myfifo",O_RDONLY);
if(fd < 0){
perror("writer open err");
exit(0);
}
//读内容
while(1)
{
char readbuf[32]={0};
int ret = read(fd,readbuf,sizeof(readbuf));
if(ret < 0){
printf("readbuf error\n");
return -2;
}
printf("readbuf success!\n");
printf("readbuf=%s",readbuf);
sleep(1);
}
return 0;
}
其中"write.cpp
"代码如下:
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
int main()
{
int fd = open("./myfifo",O_WRONLY);
if(fd < 0){
perror("writer open err");
exit(0);
}
//写内容
while(1){
char writebuf[]="hellow";
int ret = write(fd,writebuf,sizeof(writebuf));
if(ret < 0){
printf("write error\n");
return -2;
}
printf("write success!\n");
printf("writebuf=%s",writebuf);
sleep(1);
}
return 0;
}
3.运行代码进行查看
可以发现,第一个进程负责向该管道对象不停的写数据,第二个进程负责向该管道对象不停的读数据。
此外:
(1)如果暂时没有数据写入管道, 读进程会在函数内部阻塞等待数据数据写入再读。
(2)如果暂时没有数据读出管道, 写进程 会在函数内部阻塞等待数据数据读出再写。
致谢:
参考的学习链接:https://blog.csdn.net/weixin_51156269/article/details/126444169