epoll的一些发现(linux | c | cpp)(一)

1.epoll+信号

之前用的都是epoll+多线程/线程池

现在由信号触发,基本的模型可以写为(初始化套接字之类的,以及epoll初始化省略)

while( !stop) 	
{
	int number = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
	if ( number < 0 && errno != EINTR)  
        {
			//打印错误并退出
			break;
	}

	for ( int i = 0; i < number; i++ ) 
        {
		int sockfd = events[i].data.fd;
		if ( sockfd == listenfd ) 
		{
			//accept返回套接字加入epoll中
		}
		else if ( events[i].events & EPOLLIN ) 
		{
			//信号处理函数处理
		} 
		else {
			//处理其他情况
		}
	}
}


但是如果是信号函数想返回某些值以供分析处理的话,这样直接丢出去是不行的

可以选择用管道,但是要全双工通信,还要建立两个pipe,有没有更好的解决方法呢,答案是有

函数在这里 更详细可以查man手册

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sv[2]);

这个函数的功能是创建一个无名管道(就是两个套接字sv[0] sv[1]),父进程关闭sv[0],在sv[1]接收和发送,子进程关闭sv[1],在sv[0]接收发送

原本用于两个进程间通信

例子代码在这里

https://code.csdn.net/snippets/530935


我们可以通过这种方法达到目的

static int pipefd[2];

void sig_hander(int sig)
{
    //保留原来的errno, 在函数最后恢复,以保证函数的可重入性
    int save_errno = errno;
    int msg = sig;
    //通过pipefd[1]向父进程发送信息
    send(pipefd[1], (char*)&msg, 1, 0);
    errno = save_errno;
}

int main(int argc, char** argv)
{
        //省略套接字初始化
        //省略epoll初始化
        //设置信号处理函数
	while (!stop_server)
	{
		int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if ((number < 0) && (errno != EINTR))
		{
			printf("epoll failure\n");
			break;
		}
		for ( int i = 0; i < number; i++)
		{
			int sockfd = events[i].data.fd;
			if (sockfd == listenfd)
			{
				struct sockaddr_in client_address;
				socklen_t client_addrlength = sizeof(client_address);
				int connfd = accept(listenfd, (struct sockaddr*)&client_address, &client_addrlength);
				addfd(epollfd, connfd);
			}
			//如果文件描述符是pipefd[0] 则处理信号
                        else if ((sockfd == pipefd[0]) && (events[i].events & EPOLLIN))
			{
                                //处理信号
         		}
		}
         }
	return 0;
} 



完整代码在这里


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值