libevent_通过libevent监听有名管道
libevent_IO事件
管道是通过文件描述符读写,我们可以监听文件描述符是否可读,一旦有进程往管道中写数据,另一端就是可读,可以被libevent监听到。libevent监听到后,可以调用函数将数据读取出来。有名管道随便读写,读和写是通过fd,将这个fd添加到集合中,libevent可以监听这个fd,一旦发现这个fd可读,就将数据读出来。
整体流程,分为A和B两个部分,A部分为创建一个读进程,B部分为创建一个写进程。
A :创建一个读管道进程。
1. 创建有名管道。调用函数mkfifo(const char *pathname, mode_t mode)
2. 打开管道。调用函数open(const char *pathname, int flags, mode_t mode)
3. 初始化事件集合。调用函数event_init()
4. 创建一个事件。定义一个结构体变量struct event ev
5. 初始化事件,fd和事件绑定一起。调用函数event_set(&ev, fd, EV_READ, fifo_read, NULL);
6.实现fifo_read函数。
7. 事件添加到集合中。调用函数event_add(&ev, NULL),默认情况下文件描述符只能使用一次。
8. 开始监听。调用函数event_dispatch()
B:创建一个写管道进程。
读管道进程源代码:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <event.h> void fifo_read(evutil_socket_t fd, short events, void *arg){ char buf[200] = {0}; int ret = 0; ret = read(fd, buf, sizeof(buf)); if(ret == -1){ printf("readFIFO文件出错\n"); return -1; } printf("从fifo管道中读取数据[%s]\n", buf); } int main(int argc, char *argv[]){ int ret = 0; ret = mkfifo("/home/xl/FileDemo/mkfifo_1", 00700); if(ret == -1){ printf("mkfifo创建FIFO文件失败\n"); return 0; } int fd = 0; fd = open("/home/xl/FileDemo/mkfifo_1", O_RDONLY); if(fd == -1){ printf("open 打开文件失败\n"); return -1; } struct event ev; event_init(); event_set(&ev, fd, EV_READ|EV_PERSIST, fifo_read, NULL); event_add(&ev, NULL); event_dispatch(); return 0; }
写管道进程源代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char *argv[]){ int ret = 0; int w_ret = 0; char home_path[200] = {0}; char file_path[200] = {0}; char file_name[200] = {0}; char s_buf[200] = {0}; strcpy(home_path, getenv("HOME")); sprintf(file_path , "%s/%s/%s", home_path, "FileDemo" ,"mkfifo_1"); strcpy(file_name, file_path); printf("file_name = [%s]\n", file_name); ret = open(file_name, O_WRONLY); if(ret == -1){ printf("打开文件[%s]失败", file_name); return -1; } while(1){ scanf("%s", s_buf); if(!strcmp(s_buf, "bye")){ printf("bye~~~\n"); break; } w_ret = write(ret, s_buf, sizeof(s_buf)); if(w_ret == -1){ printf("写入数据[%s]失败", s_buf); return -1; } memset(s_buf, 0x00, sizeof(s_buf)); } printf("exit!!!\n"); return 0; }
通过简单的代码,学习事件集合是什么? 事件是什么? 事件如何添加到事件集合中?怎么把文件描述符和事件关联起来?
代码中使用到的函数源代码
event_init
struct event_base *event_init(void) { struct event_base *base = event_base_new_with_config(NULL); if (base == NULL) { event_errx(1, "%s: Unable to construct event_base", __func__); return NULL; } current_base = base; //这里current_base 是一个全局变量。 return (base); }
event_set函数原型
/** Prepare an event structure to be added. @deprecated event_set() is not recommended for new code, because it requires a subsequent call to event_base_set() to be safe under most circumstances. Use event_assign() or event_new() instead. */ EVENT2_EXPORT_SYMBOL void event_set(struct event *, evutil_socket_t, short, void (*)(evutil_socket_t, short, void *), void *);
posted on 2020-12-03 22:15 XiaoXiaoli 阅读(649) 评论(0) 收藏 举报
浙公网安备 33010602011771号