命名管道可以从命令行上创建,命令行方法是使用下面这个命令。
$ mkfifo filename
上图可见进程间通信成功。
命名管道也可以从程序里创建,相关函数有
int mkfifo(const char *filename,mode_t mode);
查手册:
man 3 mkfifo
#ifndef _LOG_H_
#define _LOG_H_
#include
#include
enum e
{
Debug,
Notice,
Warning,
Error
};
const std::string msg[]{
"Debug",
"Notice",
"Warning",
"Error"};
std::ostream &log(std::string message, int level)
{
std::cout << " | " << (unsigned)time(nullptr) << " | " << msg[level] << " | " << message;
return std::cout;
}
#endif
#ifndef _COMM_H_
#define _COMM_H
#include
#include
#include
#include
#include
#include
using namespace std;
#define MODE 0666
#define SIZE 128
string ipcpath = "./fifo.ioc";
#endif
#include "comm.hpp"
#include "log.hpp"
int main()
{
// 1. 创建管道文件
if (mkfifo(ipcpath.c_str(), MODE) < 0)
{
perror("mkfifo");
exit(1);
}
log("创建管道文件成功", Debug) << " step 1" << endl;
// 2. 正常的文件操作
int fd = open(ipcpath.c_str(), O_RDONLY);
if (fd < 0)
{
perror("open");
exit(2);
}
log("打开管道文件成功", Debug) << " step 2" << endl;
// 3. 编写正常代码
char buffer[SIZE];
while (true)
{
ssize_t s = read(fd, buffer, sizeof(buffer) - 1);
if (s > 0)
{
cout << "[" << getpid() << "]"
<< "client say " << buffer << endl;
}
else if (s == 0)
{
// end of file
cerr << "[" << getpid() << "]"
<< "read end of file, client quit, server quit too!" << endl;
break;
}
else
{
// read error
perror("read");
exit(3);
break;
}
}
// 4. 关闭文件
close(fd);
log("关闭管道文件成功", Debug) << " step 3" << endl;
unlink(ipcpath.c_str()); //通信完毕,就删除文件
log("删除管道文件成功", Debug) << " step 4" << endl;
return 0;
}
#include "comm.hpp"
int main()
{
// 1. 获取管道文件
int fd = open(ipcpath.c_str(), O_WRONLY);
if (fd < 0)
{
perror("open");
exit(1);
}
// 2. ipc过程
string buffer;
while (true)
{
cout << "请输入一行信息 :> ";
getline(cin, buffer);
write(fd, buffer.c_str(), buffer.size());
}
// 3. 关闭
close(fd);
return 0;
}
#include "comm.hpp"
#include "log.hpp"
#include
static void getMessag(int fd)
{
char buffer[SIZE];
while (true)
{
ssize_t s = read(fd, buffer, sizeof(buffer) - 1);
if (s > 0)
{
cout << "[" << getpid() << "]"
<< "client say " << buffer << endl;
}
else if (s == 0)
{
// end of file
cerr << "[" << getpid() << "]"
<< "read end of file, client quit, server quit too!" << endl;
break;
}
else
{
// read error
perror("read");
exit(3);
break;
}
}
}
int main()
{
// 1. 创建管道文件
if (mkfifo(ipcpath.c_str(), MODE) < 0)
{
perror("mkfifo");
exit(1);
}
log("创建管道文件成功", Debug) << " step 1" << endl;
// 2. 正常的文件操作
int fd = open(ipcpath.c_str(), O_RDONLY);
if (fd < 0)
{
perror("open");
exit(2);
}
log("打开管道文件成功", Debug) << " step 2" << endl;
for (int i = 0; i < 3; i++)
{
pid_t id = fork();
if (id == 0)
{
// 3. 编写正常代码
getMessag(fd);
exit(0);
}
}
for (int i = 0; i < 3; i++)
{
waitpid(-1, nullptr, 0);
}
// 4. 关闭文件
close(fd);
log("关闭管道文件成功", Debug) << " step 3" << endl;
unlink(ipcpath.c_str()); //通信完毕,就删除文件
log("删除管道文件成功", Debug) << " step 4" << endl;
return 0;
}