Libevent IO事件

目录

Note

利用Libevent创建监听集合,将管道的读端与事件绑定并放入监听集合中,在管道另一端写内容,监听集合一旦监听到就会自动触发读取管道内内容

管道服务端

注意:编译的时候要加libevent库, gcc 管道服务端.c -o 管道服务端 -levent

// ##############################################################################################
	//初始化事件(把fd和事件ev绑定) 参数:关联的文件描述符 事件类型 回调函数 回调函数参数
	/*******函数原型 BEGIN********
	struct event_base *event_init(void);

	void
	event_set(struct event *ev, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
	参数说明:
	** this flag to event_for new()/event_assign() to get a timeout.
	//#define EV_TIMEOUT	0x01
	** Wait for a socket or FD to become readable
	//#define EV_READ		0x02
	** Wait for a socket or FD to become writeable
	//#define EV_WRITE	0x04
	** Wait for a POSIX signal to be raised
	//#define EV_SIGNAL	0x08
	**
 	* Persistent event: won't get removed automatically when activated.
 	*
 	* When a persistent event with a timeout becomes activated, its timeout
 	* is reset to 0.
 	**
	#define EV_PERSIST	0x10
	** Select edge-triggered behavior, if supported by the backend. **
	#define EV_ET		0x20
	**
 	* If this option is provided, then event_del() will not block in one thread
 	* while waiting for the event callback to complete in another thread.
 	*
 	* To use this option safely, you may need to use event_finalize() or
 	* event_free_finalize() in order to safely tear down an event in a
 	* multithreaded application.  See those functions for more information.
 	**
	#define EV_FINALIZE     0x40
	**
 	* Detects connection close events.  You can use this to detect when a
 	* connection has been closed, without having to read all the pending data
 	* from a connection.
 	*
 	* Not all backends support EV_CLOSED.  To detect or require it, use the
 	* feature flag EV_FEATURE_EARLY_CLOSE.
	**
	#define EV_CLOSED	0x80

	********函数原型 END*********/
// ##############################################################################################

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <event.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/********回调函数 BEGIN ******
原型:void (*callback)(evutil_socket_t, short, void *)
*********回调函数 END ********/
void fifo_read(evutil_socket_t fd, short events, void *arg)
{
	char buf[32] = {0};
	int ret = read(fd, buf, sizeof(buf));
	if(-1 == ret)
	{
		perror("read err");
		exit(1);
	}

	printf("从管道内读取 %s\n", buf);
}

int main()
{
	int ret = mkfifo("fifo.temp",00700); //创建管道,成功返回1失败返回0;参数1管道文件,参数2权限
	if(-1 == ret)
	{
		perror("mkfifo");
		exit(1);
	}

	int fd = open("fifo.temp", O_RDONLY); //打开管道,设置只读取
	if(-1 == fd)
	{
		perror("open err");
		exit(1);
	}

	/********** 1、把管道fd与事件绑定 2、将事件加入到事件集合 3、**********/
	//创建事件
	struct event ev;

	//初始化事件集合
	event_init();

	event_set(&ev, fd, EV_READ|EV_PERSIST, fifo_read, NULL);  //EV_PERSIST 设置即使集合中没有事件监听,也不会退出

	//把事件添加到集合中
	event_add(&ev, NULL);

	//开启监听,死循环, 如果集合中没有事件监听则返回
	event_dispatch();
	return 0;
}

管道客户端

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

int main()
{
	//创建有名管道
	//int ret = mkfifo("fifo.temp", 00400 | 00200);
	//if(-1 == ret)
	//{
	//	perror("mkfifo err");
	//	exit(1);
	//}

	//默认是阻塞的
	int fd = open("fifo.temp", O_WRONLY);
	if(-1 == fd)
	{
		perror("open err");
		exit(1);
	}

	int ret;
	char buf[32] = {0};
	while(1)
	{
		scanf("%s" ,buf);
		ret = write(fd, buf, strlen(buf));
		if(-1 == ret)
		{
			perror("write");
			exit(1);
		}

		if(!strcmp(buf, "bye"))
		{
			break;
		}

		memset(buf, 0, sizeof(buf));
	}
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦