Linux/C/C++ epoll网络服务端多线程实现-EPOLLONESHOT事件

demo.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>
#include <poll.h>

#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>


#define BUFFER_LENGTH	5
#define EPOLL_SIZE		1024

struct fds
{
   
	int epoll_fd;
	int clientfd;
};

/* 设置文件描述符为非阻塞 */
int setNonBlocking(int sockfd)
{
   
	// 先获取fd的属性再和非阻塞属性做或运算
	if (-1 == fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK))
	{
   
		return -1;
	}

	return 0;
}

// 我们希望在任何时候sockfd都由一个线程处理, 所以采用EPOLLONESHOT事件, 保证线程安全
// oneshot 指定是否注册fd上的EPOLLONESHOT事件
// 尤其注意监听socketfd不能注册EPOLLONESHOT事件, 否则应用程序只能处理一个客户连接! 因为后续的客户连接请求将不再触发listenfd上的EPOLLIN事件
void epollAddFd(int epollfd, int fd, int oneshot)
{
   
	struct epoll_event event;
	event.data.fd = fd;
	event.events = EPOLLIN | EPOLLET;
	if (oneshot)
	{
   
		event.events |= EPOLLONESHOT;
	}
	setNonBlocking(fd);
	epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
}

// 重置fd上的事件, 这样操作后, 尽管fd上的EPOLLONESHOT事件被注册, 但是操作系统仍然会触发fd上的EPOLLIN事件, 且只触发一次
void reset_oneshot(int epollfd, int fd)
{
   
	struct epoll_event event;
	event.data.fd = fd;
	event.events = EPOLLIN 
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值