libevent(七)事件循环退出

在这里插入图片描述

#include <iostream>
#include <event2/event.h>
#ifndef _WIN32
#include <signal.h>
#endif
using namespace std;

bool isexit = false;


//sock文件描述符, which事件类型, arg传递的参数
static void Ctrl_C(int sock, short which, void* arg) {
	cout << "INPUT:>> Ctrl+C" << endl;
	event_base* base = (event_base*)arg;

	//执行完当前处理的事件函数就退出
	//event_base_loopbreak(base);

	//运行完所有的活动事件再退出;事件循环没有运行时,也要等运行一次再退出;
	timeval t = { 3,0 };         //至少运行3秒后退出。
	event_base_loopexit(base, &t);
}

static void Kill(int sock, short which, void* arg) {
	cout << "INPUT:>> Kill" << endl;
	//如果处于非待决
	event* ev = (event*)arg;
	if (!evsignal_pending(ev, NULL))
	{
		event_del(ev);
		event_add(ev, NULL);
	}
}

int main(int argc, char** argv) {
#if _WIN32
	//windowns 初始化socket库
	WSADATA wsa;
	WSAStartup(MAKEWORD(2, 2), &wsa);
#else
	//linux 忽略管道信号,发送数据给已关闭的socket
	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
		return 1;
#endif
	event_base* base = event_base_new();

#ifndef _WIN32
	//添加信号Ctrl+C 处于no_pending(隐藏的状态:EV_SIGNAL|EV_PERSIST)
	event* c_signal = evsignal_new(base, SIGINT, Ctrl_C, base);
	if (!c_signal){
		cerr << "SIGINT evsignal_new failed \n";
		return -1;
	}

	//添加事件到pending
	if (event_add(c_signal, 0) != 0) {
		cerr << "SIGINT event_add failed \n";
		return -1;
	}

	//添加kill信号 (非持久,一次性, event_self_cbarg传递当前event)
	event* k_signal = event_new(base, SIGTERM, EV_SIGNAL, Kill, event_self_cbarg());
	if (!k_signal) {
		cerr << "k_signal evsignal_new failed \n";
		return -1;
	}

	//添加事件到pending
	if (event_add(k_signal, 0) != 0) {
		cerr << "SIGINT k_signal failed \n";
		return -1;
	}

	//进入事件主循环
	//event_base_dispatch(base);

	// 事件主循环的三种示例
	// EVLOOP_ONCE     等待一个事件运行,直到没有活动事件就退出
	// event_base_loop(base, EVLOOP_NONBLOCK);

	// EVLOOP_NONBLOCK 有活动事件就处理,没有就返回0 (启动程序无活动就退出了)
	//while (!isexit)
	//{
	//	event_base_loop(base, EVLOOP_NONBLOCK);
	//}

	// EVLOOP_NO_EXIT_ON_EMPTY m没有注册事件也不返回,用于事件后期多线程添加
	event_base_loop(base, EVLOOP_NO_EXIT_ON_EMPTY);

	event_free(c_signal);
	event_base_free(base);
#endif // _WIN32
#ifdef _WIN32
	WSACleanup();
#endif // _WIN32
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
libevent是一个开源的事件驱动库,可以用于开发高性能的多线程服务器架构。它提供了一组API,可以处理各种事件,如网络连接、定时器和信号等。以下是一个基本的libevent多线程服务器架构的示例: 1. 初始化libevent库:在服务器启动时,首先需要初始化libevent库,并创建一个libevent的上下文对象。 2. 创建监听socket:使用libevent提供的API创建一个监听socket,用于接收客户端的连接请求。 3. 注册事件回调函数:通过使用libevent提供的API,将监听socket的读事件(即有新的连接请求)注册到libevent事件循环中,并指定对应的回调函数。 4. 创建工作线程池:为了处理多个客户端连接,可以创建一个工作线程池。每个工作线程都负责处理一个或多个客户端连接。 5. 接收客户端连接:当有新的客户端连接请求到达时,libevent会触发注册的回调函数。在回调函数中,可以接受客户端连接,创建新的套接字,并将其注册到libevent事件循环中。 6. 分发工作:当新的客户端连接被接受后,可以选择将其分发给工作线程池中的某个线程进行处理。可以使用线程池管理库或手动实现线程池。 7. 处理客户端请求:在工作线程中,可以通过libevent事件循环处理客户端的读写事件。可以注册读事件来接收客户端发送的数据,注册写事件来发送响应数据。 8. 关闭连接:当客户端断开连接或发生错误时,需要关闭对应的套接字,并从libevent事件循环中移除。 以上是一个简单的libevent多线程服务器架构的基本步骤。实际应用中,还可以结合其他技术和设计模式来实现更复杂的功能和性能优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SongpingWang

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值