C++ 使用 mmap 和 epoll 实现多线程读写
以下是基于 mmap 和 epoll 的 C++ 实现,使用两个线程分别处理写消息和读消息:
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/epoll.h>
#include <cstring>
#include <thread>
#define MAX_EVENTS 10
#define BUF_SIZE 1024
using namespace std;
void write_thread(char *mmap_ptr, int epoll_fd) {
struct epoll_event ev, events[MAX_EVENTS];
int n, fd;
char buf[BUF_SIZE];
while (true) {
// 从标准输入读取数据
n = read(STDIN_FILENO, buf, BUF_SIZE);
if (n == 0) break;
// 将数据写入 mmap 内存区域
memcpy(mmap_ptr, buf, n);
// 触发写事件
ev.events = EPOLLOUT;
ev.data.fd = epoll_fd;
epoll_ctl(epoll_fd, EPOLL_CTL_MOD, STDIN_FILENO, &ev);
// 等待事件完成
epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
}
}
void read_thread(char *mmap_ptr, int epoll_fd) {
struct epoll_event ev, events[MAX_EVENTS];
int n, fd;
char buf[BUF_SIZE];
while (true) {
// 等待读事件
epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
// 从 mmap 内存区域读取数据
memcpy(buf, mmap_ptr, BUF_SIZE);
// 将数据输出到标准输出
write(STDOUT_FILENO, buf, strlen(buf));
}
}
int main() {
int fd = open('mmap_file', O_CREAT | O_RDWR, 0666);
ftruncate(fd, BUF_SIZE);
char *mmap_ptr = (char *) mmap(nullptr, BUF_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
int epoll_fd = epoll_create1(0);
struct epoll_event ev, events[MAX_EVENTS];
ev.events = EPOLLIN;
ev.data.fd = STDIN_FILENO;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ev);
thread write_th(write_thread, mmap_ptr, epoll_fd);
thread read_th(read_thread, mmap_ptr, epoll_fd);
write_th.join();
read_th.join();
munmap(mmap_ptr, BUF_SIZE);
close(epoll_fd);
return 0;
}
该代码创建了一个大小为 1024 的 mmap 内存区域,并将其映射到名为“mmap_file”的文件中。其中,write_thread 函数从标准输入读取数据,并将其写入 mmap 内存区域中;read_thread 函数从 mmap 内存区域读取数据,并将其输出到标准输出中。两个线程分别处理读写操作,通过 epoll 机制实现事件触发和等待。
原文地址: https://www.cveoy.top/t/topic/mrv2 著作权归作者所有。请勿转载和采集!