当前位置:网站首页>Epolloneshot event of epoll -- instance program
Epolloneshot event of epoll -- instance program
2022-04-23 14:40:00 【m0_ fifty-one million five hundred and fifty-one thousand three】
This example program is a server , He receives user data , And output to standard output , He is characterized by : For each of these EPOLLIN event , Wake up a thread to deal with him , And the main process continues to execute , That is to enter the next cycle , call epoll_wait Listen for other events .
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<assert.h>
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/epoll.h>
#include<pthread.h>
#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 1024
struct fds
{
int epollfd;
int sockfd;
};
int setnonblocking(int fd)
{
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(fd, F_SETFL, new_option);
return old_option;
}
/* take fd Upper EPOLLIN and EPOLLET Event registration to epollfd Directed epoll In the kernel event table , Parameters oneshot Specify whether to register fd Upper EPOLLONESHOT event */
void addfd(int epollfd, int fd, bool oneshot)
{
epoll_event event;
event.events = EPOLLIN | EPOLLET;
if (oneshot)
{
event.events |= EPOLLONESHOT;
}
epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event);
setnonblocking(fd);
}
/* Reset fd Events on the . After doing this , Even though fd Upper EPOLLONESHOT Event is registered , But the operating system still triggers fd Upper EPOLLIN event , And trigger only once */
void reset_oneshot(int epollfd, int fd)
{
epoll_event event;
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &event);
}
/* The worker thread */
void* worker(void* arg)
{
int sockfd = ((fds*)arg)->sockfd;
int epollfd = ((fds*)arg)->epollfd;
printf("start new thread to receive data on fd %d\n", sockfd);
char buf[BUFFER_SIZE];
memset(buf, '\0', BUFFER_SIZE);
/* Cyclic reading sockfd The data on the , Guide encountered EAGAIN error */
while (1)
{
int ret = recv(sockfd, buf, BUFFER_SIZE - 1, 0);
if (ret == 0)
{
close(sockfd);
printf("foreiner closed the connection\n");
break;
}
else if (ret < 0)
{
if (errno == EAGAIN)
{
reset_oneshot(epollfd, sockfd);
printf("read later\n");
break;
}
}
else
{
printf("get content: %s\n", buf);
/* Sleep 5s, Simulate the data processing process */
sleep(5);
}
}
printf("end thread receiving data on fd: %d\n", sockfd);
}
int main(int argc, char* argv[])
{
if (argc <= 2)
{
return 1;
}
const char* ip = argv[1];
int port = atoi(argv[2]);
int ret = 0;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(port);
inet_pton(AF_INET, ip, &address.sin_addr);
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
assert(listenfd >= 0);
ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));
assert(ret != -1);
ret = listen(listenfd, 5);
assert(ret != -1);
epoll_event events[MAX_EVENT_NUMBER];
int epollfd = epoll_create(10);
assert(epollfd != -1);
/* Be careful , monitor sockfd listenfd Can't register on EPOLLONESHOT event , Otherwise, because the program can only handle one client connection ! Because the connection request of subsequent customers will no longer trigger listenfd Upper EPOLLIN event */
addfd(epollfd, listenfd, false);
while (1)
{
int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
if (ret < 0)
{
printf("epoll failure\n");
break;
}
for (int i = 0; i < ret; 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);
/* Register for each non listening file descriptor EPOLLONESHOT event */
addfd(epollfd, connfd, true);
}
else if (events[i].events & EPOLLIN) /* For each EPOLLIN Event opens a thread , Then the process proceeds to the next epoll_wait */
{
pthread_t thread;
fds fds_for_new_worker;
fds_for_new_worker.epollfd = epollfd;
fds_for_new_worker.sockfd = sockfd;
/* Start a new worker thread as sockfd service */
pthread_create(&thread, NULL, worker, (void*)&fds_for_new_worker);
}
else
{
printf("something else happened\n");
}
}
}
close(listenfd);
return 0;
}
版权声明
本文为[m0_ fifty-one million five hundred and fifty-one thousand three]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231435333870.html
边栏推荐
猜你喜欢

Matlab Simulink modeling and design of single-phase AC-AC frequency converter, with MATLAB simulation, PPT and papers

四层和八层电梯控制系统Proteus仿真设计,51单片机,附仿真和Keil C代码

ArrayList集合基本使用

51 MCU + LCD12864 LCD Tetris game, proteus simulation, ad schematic diagram, code, thesis, etc

QT Detailed explanation of pro file

Find daffodils - for loop practice

想要成为架构师?夯实基础最重要

Electronic perpetual calendar of DS1302_ 51 single chip microcomputer, month, day, week, hour, minute and second, lunar calendar and temperature, with alarm clock and complete set of data

Qt实战:云曦日历篇

Swift Protocol 关联对象 资源名称管理 多线程GCD 延迟 once
随机推荐
ArrayList collection basic usage
Want to be an architect? Tamping the foundation is the most important
Swift Protocol 关联对象 资源名称管理 多线程GCD 延迟 once
Proteus simulation design of four storey and eight storey elevator control system, 51 single chip microcomputer, with simulation and keil c code
全连接层的作用是什么?
金九银十,入职字节跳动那一天,我哭了(蘑菇街被裁,奋战7个月拿下offer)
Parameter stack pressing problem of C language in structure parameter transmission
1-初识Go语言
基于TLC5615的多路可调数控直流稳压电源,51单片机,含Proteus仿真和C代码等
初识STL
如何5分钟上手使用OCR
Unity_代码方式添加绑定按钮点击事件
Mq-2 and DS18B20 fire temperature smoke alarm system design, 51 single chip microcomputer, with simulation, C code, schematic diagram, PCB, etc
TLC5615 based multi-channel adjustable CNC DC regulated power supply, 51 single chip microcomputer, including proteus simulation and C code
I thought I could lie down and enter Huawei, but I was confused when I received JD / didi / iqiyi offers one after another
你还不知道责任链模式的使用场景吗?
L'externalisation a duré quatre ans.
Swift:Entry of program、Swift调用OC、@_silgen_name 、 OC 调用Swift、dynamic、String、Substring
【NLP】HMM隐马尔可夫+维特比分词
【无标题】