- linux 2.6内核epoll用法举例说明(续)--给echo服务器增加读线程池
- 上篇文章使用linux内核2.6 提供的epoll机制实现了一个反应式echo服务器,使用反应式服务器的最大好处就是可以按cpu的数量来配置线程池内线程的线程数而不是根据客户端的并发量配置线程池。我是第一次使用pthread库来写线程池,使用的是工作队列方式的线程池。我感觉作队列方式的线程池可以当成一种设计模式来用的,在很多平台上都是可以按这种方式来实现线程池,从win32 ,unix到jvm都是适用的
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #define MAXLINE 10
- #define OPEN_MAX 100
- #define LISTENQ 20
- #define SERV_PORT 5555
- #define INFTIM 1000
- //线程池任务队列结构体
- struct task{
- int fd; //需要读写的文件描述符
- struct task *next; //下一个任务
- };
- //用于读写两个的两个方面传递参数
- struct user_data{
- int fd;
- unsigned int n_size;
- char line[MAXLINE];
- };
- //线程的任务函数
- void * readtask(void *args);
- void * writetask(void *args);
- //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
- struct epoll_event ev,events[20];
- int epfd;
- pthread_mutex_t mutex;
- pthread_cond_t cond1;
- struct task *readhead=NULL,*readtail=NULL,*writehead=NULL;
- void setnonblocking(int sock)
- {
- int opts;
- opts=fcntl(sock,F_GETFL);
- if(opts<0)
- {
- perror("fcntl(sock,GETFL)");
- exit(1);
- }
- opts = opts|O_NONBLOCK;
- if(fcntl(sock,F_SETFL,opts)<0)
- {
- perror("fcntl(sock,SETFL,opts)");
- exit(1);
- }
- }
- int main()
- {
- int i, maxi, listenfd, connfd, sockfd,nfds;
- pthread_t tid1,tid2;
- struct task *new_task=NULL;
- struct user_data *rdata=NULL;
- socklen_t clilen;
- pthread_mutex_init(&mutex,NULL);
- pthread_cond_init(&cond1,NULL);
- //初始化用于读线程池的线程
- pthread_create(&tid1,NULL,readtask,NULL);
- pthread_create(&tid2,NULL,readtask,NULL);
- //生成用于处理accept的epoll专用的文件描述符
- epfd=epoll_create(256);
- struct sockaddr_in clientaddr;
- struct sockaddr_in serveraddr;
- listenfd = socket(AF_INET, SOCK_STREAM, 0);
- //把socket设置为非阻塞方式
- setnonblocking(listenfd);
- //设置与要处理的事件相关的文件描述符
- ev.data.fd=listenfd;
- //设置要处理的事件类型
- ev.events=EPOLLIN|EPOLLET;
- //注册epoll事件
- epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);
- bzero(&serveraddr, sizeof(serveraddr));
- serveraddr.sin_family = AF_INET;
- char *local_addr="200.200.200.222";
- inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);
- serveraddr.sin_port=htons(SERV_PORT);
- bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
- listen(listenfd, LISTENQ);
- maxi = 0;
- for ( ; ; ) {
- //等待epoll事件的发生
- nfds=epoll_wait(epfd,events,20,500);
- //处理所发生的所有事件
- for(i=0;i
- {
- if(events[i].data.fd==listenfd)
- {
- connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
- if(connfd<0){
- perror("connfd<0");
- exit(1);
- }
- setnonblocking(connfd);
- char *str = inet_ntoa(clientaddr.sin_addr);
- std::cout<<"connec_ from >>"<
- //设置用于读操作的文件描述符
- ev.data.fd=connfd;
- //设置用于注测的读操作事件
- ev.events=EPOLLIN|EPOLLET;
- //注册ev
- epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
- }
- else if(events[i].events&EPOLLIN)
- {
- printf("reading!/n");
- if ( (sockfd = events[i].data.fd) < 0) continue;
- new_task=new task();
- new_task->fd=sockfd;
- new_task->next=NULL;
- //添加新的读任务
- pthread_mutex_lock(&mutex);
- if(readhead==NULL)
- {
- readhead=new_task;
- readtail=new_task;
- }
- else
- {
- readtail->next=new_task;
- readtail=new_task;
- }
- //唤醒所有等待cond1条件的线程
- pthread_cond_broadcast(&cond1);
- pthread_mutex_unlock(&mutex);
- }
- else if(events[i].events&EPOLLOUT)
- {
- rdata=(struct user_data *)events[i].data.ptr;
- sockfd = rdata->fd;
- write(sockfd, rdata->line, rdata->n_size);
- delete rdata;
- //设置用于读操作的文件描述符
- ev.data.fd=sockfd;
- //设置用于注测的读操作事件
- ev.events=EPOLLIN|EPOLLET;
- //修改sockfd上要处理的事件为EPOLIN
- epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
- }
- }
- }
- }
- void * readtask(void *args)
- {
- int fd=-1;
- unsigned int n;
- //用于把读出来的数据传递出去
- struct user_data *data = NULL;
- while(1){
- pthread_mutex_lock(&mutex);
- //等待到任务队列不为空
- while(readhead==NULL)
- pthread_cond_wait(&cond1,&mutex);
- fd=readhead->fd;
- //从任务队列取出一个读任务
- struct task *tmp=readhead;
- readhead = readhead->next;
- delete tmp;
- pthread_mutex_unlock(&mutex);
- data = new user_data();
- data->fd=fd;
- if ( (n = read(fd, data->line, MAXLINE)) < 0) {
- if (errno == ECONNRESET) {
- close(fd);
- } else
- std::cout<<"readline error"<
- if(data!=NULL)delete data;
- } else if (n == 0) {
- close(fd);
- printf("Client close connect!/n");
- if(data!=NULL)delete data;
- } else{
- data->n_size=n;
- //设置需要传递出去的数据
- ev.data.ptr=data;
- //设置用于注测的写操作事件
- ev.events=EPOLLOUT|EPOLLET;
- //修改sockfd上要处理的事件为EPOLLOUT
- epoll_ctl(epfd,EPOLL_CTL_MOD,fd,&ev);
- }
- }
- }
相关推荐
逆向分析TikTok的Cronet网络库:定位libsscronet.so并Hook关键SSL函数
本文深入探讨了逆向分析TikTok的Cronet网络库的技术细节,重点介绍了如何定位libsscronet.so并Hook关键SSL函数。通过Java到Native的调用链路追踪、So库定位策略和SSL验证函数的动态Hook技巧,帮助开发者突破定制化网络库的协议加密防护,实现流量解密和协议分析。
epoll哪些触发模式_网络编程:epoll
前言前面讲了IO多路复用的API,select和poll的缺点是性能不够,客户端连接越多性能下降越明显,epoll的出现解决了这个问题,引用The Linux Programming Interface的一个统计对比如下:fd数量 poll CPU时间(秒) select CPU时间(秒) epoll CPU时间(秒) -----------------------------...
Flutter 中使用蓝牙插件报错,说没有权限怎么解决
2、在build.grale里面更改一下版本号,我修改的是targetSdkVersion这个版本号,需要根据你自己的版本进行更改,记得更改之后先flutter clean一下再run。搞了一晚上,没搞出来,第二天用同事手机测试发现他手机可以,我手机还是不行,才发现是Android版本问题,需要修改两处地方。废话不多说,咱先看报错信息。
epoll编程实例客户端_Python epoll网络编程二:客户端模型
Python epoll网络编程二:客户端模型第一篇简单介绍了一个使用epoll的服务器模型,本节介绍使用epoll的客户端模型,客户端连接多个服务器。以下是发送hello请求的客户端,可以作为探测程序,探测服务器的工作状态,如果返回greeting,表示服务器正常工作。代码如下:文件:epoll_python.zip大小:2KB下载:def usage():print 'python epoll...
[面试]SoC验证工程师面试常见问题(三)
SoC 验证工程师面试中,SystemVerilog、UVM 和 SystemC 的代码题目通常涵盖面向对象编程、约束随机化、UVM 组件设计、内存建模等主题。通过练习上述示例题目和理解关键点,你可以更好地应对现场编码环节。如果有具体的面试方向(如特定协议验证)或公司偏好,可以提供更多信息,我会进一步定制题目和答案。祝你面试顺利!
EduCoder 计算机网络实验 IP协议分析
第1关:跟踪抓包 任务描述 相关知识 IPV4数据包 截获数据报 分析截获结果 使用git将本地文件推送到远程仓库永久保存 操作要求 任务描述 本关任务:使用 Ping 命令发送数据报,用 Wireshark 截获数据报,分析 IP 数据报的格式,理解 IPV4 地址的编址方法,加深对 IP 协议的理解。 相关知识 为了完成本关任务,你需要掌握: 截获数据报; 简单分析数据包格式。 IPV4数据包 网际协议第 4 版(Internet Protocol version 4
epoll_实现服务器客户端通信
【代码】epoll_实现服务器客户端通信。
深入MoveIt与OMPL集成开发:从源码编译到自定义规划算法实战
本文详细介绍了如何从源码编译集成MoveIt与OMPL,并实现自定义规划算法的完整流程。通过清理环境、获取源码、解决编译依赖与错误,最终指导开发者创建并集成名为MyRRT的自定义规划算法,从而实现对机器人运动规划栈的深度定制与优化。
linux上的epoll如何使用,并用C++实现多客户端服务器
是Linux系统中的一种高效的I/O多路复用机制,可以用于实现高并发的网络服务器。的代码相对复杂,需要理解非阻塞I/O、事件驱动编程等概念。实现多客户端服务器的基本步骤,需要注意的是,
【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)
【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)
Vue - 萤石云监控 ezuikit 视频实例销毁方案,解决使用stop方法无法销毁EZUIKit实例或销毁后依然占用内存并且监控画面依然有声音问题(解决页面多个监控摄像头画面同时播放,翻页或关闭页
vue2,vue3,萤石,监控摄像头,萤石云销毁视频实例,退出页面销毁,stop销毁原视频流,占用内存怎么办,销毁后视频依旧在后台播放有声音,销毁视频播放器,页面上有多个视频画面怎么销毁某一个,stop方法不生效怎么办,浏览器非常卡,dom销毁,ezuikit-js萤石云播放器Vue中使用beforeDestory销毁播放器实例,调用萤石云ezuikit-js的视频对象销毁,vue使用萤石云监控视频录像回放,不销毁实例会出现离开页面后依旧有监控声音并且占内存问题,不好使,页面崩了,崩溃,视频监控太多,没有用
socket创建失败_linux下socket采用epoll编程demo
首先,需要调用epoll_create创建epoll; 此后我们就可以进行socket/bind/listen; 然后调用epoll_ctl进行注册; 接下来,就可以通过一个while(1)循环调用epoll_wait来等待事件的发生; 然后循环查看接收到的事件并进行处理; 1)如果事件是sever的socketfd我们就要进行accept,并且把接收到client的socketfd加入到要监听的...
计算机控制技术及应用
《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。
linux 2.6内核epoll用法举例说明
linux 2.6内核epoll用法举例说明(zz from www.csdn.net)epoll用到的所有函数都是在头文件sys/epoll.h中声明的,下面简要说明所用到的数据结构和函数:所用到的数据结构typedef union epoll_data { void *ptr; int fd; __uin
STM32F407中文手册
STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
linux2.6内核epoll用法举例说明
linux2.6内核epoll用法举例说明http://blog.csdn.net/hwz119/archive/2007/03/22/1537553.aspx epoll用到的所有函数都是在头文件sys/epoll.h中声明的,下面简要说明所用到的数据结构和函数:所用到的数据结构typedef union epoll_data {void *ptr;int fd;__uint32_t
SAP B1中文培訓教材_SDK
公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说
Linux 2.6 内核Epoll用法举例说明
epoll用到的所有函数都是在头文件sys/epoll.h中声明的,下面简要说明所用到的数据结构和函数: 所用到的数据结构: typedef union epoll_data { void *ptr; int fd; __uint32_t u32;
linux2.6内核epoll用法举例说明zz
linux 2.6内核epoll用法举例说明(续)
linux 2.6内核epoll用法举例说明(续)http://blog.csdn.net/hwz119/archive/2007/06/07/1643134.aspx 上篇文章使用linux内核2.6提供的epoll机制实现了一个反应式echo服务器,使用反应式服务器的最大好处就是可以按cpu的数量来配置线程池内线程的线程数而不是根据客户端的并发量配置线程池。我是第一次使用pthre
969



被折叠的 条评论
为什么被折叠?



