文章目录
- 七、进程间通信
- 1. 进程间通信分类
- 命名管道
- 未完待续
七、进程间通信
1. 进程间通信分类
命名管道
管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。命名管道是一种特殊类型的文件。
我们只需要使用 mkfifo 命令就可以在当前路径下创建命名管道。
Makefile:
.PHONY:all
all:pipe_server pipe_clientpipe_server:PipeServer.ccg++ -o $@ $^ -std=c++11
pipe_client:PipeClient.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f pipe_server pipe_client
Comm.hpp:
#ifndef __COMM_HPP__
#define __COMM_HPP__#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
using namespace std;#define Mode 0666
#define Path "fifo"// 命名管道类
class Fifo
{
public:Fifo(const string& path): _path(path){umask(0);// 创建命名管道int n = mkfifo(_path.c_str(), Mode);if (n == 0){cout << "mkfifo success" << endl;}else{cout << "mkfifo failed, error : " << errno << "errstring : " << strerror(errno) << endl;}}~Fifo(){// 删除命名管道int n = unlink(_path.c_str());if (n == 0){cout << "remove " << _path << " success" << endl;}else{cout << "remove failed, error : " << errno << "errstring : " << strerror(errno) << endl;}}
private:// 文件路径 + 文件名string _path;
};#endif
pipe_server(服务端接收消息):
#include "Comm.hpp"
#include <unistd.h>int main()
{// 创建命名管道Fifo fifo(Path);// 打开命名管道文件int rfd = open(Path, O_RDONLY);if (rfd < 0){cerr << "open failed, errno: " << errno << " , errnostring: " << strerror(errno) << endl;return 1;}char buffer[1024];// 循环读取管道数据while (true){ssize_t n = read(rfd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;cout << "client says: " << buffer << endl;}else if (n == 0){cout << "client quie, me too" << endl;break;}else{cerr << "read failed, errno: " << errno << " , errnostring: " << strerror(errno) << endl;break;}}// 关闭命名管道文件close(rfd);return 0;
}
pipe_client(客户端输入消息):
#include "Comm.hpp"int main()
{// 以写的方式打开命名管道文件int rfd = open(Path, O_WRONLY);if (rfd < 0){cerr << "open failed, errno: " << errno << " , errnostring: " << strerror(errno) << endl;return 1;}string inbuffer;// 循环读取用户输入并写入管道while (true){cout << "Please Enter Your Message# ";getline(cin, inbuffer);if (inbuffer == "quit") break;ssize_t n = write(rfd, inbuffer.c_str(), inbuffer.size());if (n < 0){cerr << "write failed, errno: " << errno << " , errnostring: " << strerror(errno) << endl;}}// 关闭管道文件close(rfd);return 0;
}
结果: