在Linux网络编程中如何实现信号处理和定时器功能呢_第1页
在Linux网络编程中如何实现信号处理和定时器功能呢_第2页
在Linux网络编程中如何实现信号处理和定时器功能呢_第3页
在Linux网络编程中如何实现信号处理和定时器功能呢_第4页
在Linux网络编程中如何实现信号处理和定时器功能呢_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在Linux网络编程中如何实现信号处理和定时器功能呢?关于epoll惊群问题,什么是惊群呢?比如我们在写代码过程中,使用两个线程的epoll监听socket,当socket上有事件发生时,两个epoll都会被唤醒,导致会操作同一个socket,这就是惊群,那如何解决呢?

(1)使用EPOLLEXCLUSIVE:EPOLLEXCLUSIVE是epoll的扩展选项,它允许一个线程独占一个epoll实例,从而避免了epoll的惊群问题;

(2)使用EPOLLONESHOT:对于注册了EPOLLONESHOT事件的文件描述符,操作系统最多触发一个可读,可写或者异常事件,且触发一次,这样就能确保一个线程获取事件并处理,但是需要注意的是对于监听类型(如accept)不能使用EPOLLONESHOT,否则就不能持续监听连接,对于处理完了的非监听事件,需要重置EPOLLONESHOT;第一部分:信号1、发送信号给进程#include<sys/types.h>#include<signal.h>intkill(pid_tpid,intsig);2、信号回调函数#include<signal.h>typedefvoid(&__sighandler_t)(int);__sighandler_tsignal(intsig,__sighandler_t_handler);intsigaction(intsig,conststructsigaction*act,structsigaction*oact);(1)__sighandler_t信号处理的函数指针,其中处理参数为触发信号当前值,其中有两个默认宏(SIG_DFL:使用信号默认处理,SIG_IGN:忽略目标信号);

(2)signal注册信号回调处理函数,返回值为一个函数指针,含义是这个信号上一次处理的回调函数或者是系统默认的处理函数,这里目的是让用户可以自己恢复信号处理方式,比如系统对于一些信号是杀掉进程的,这里就应该处理完自己的回调逻辑后再调用系统默认行为;

(3)sigaction函数的功能是检查或修改与指定信号相关联的处理动作,使用样例如下:#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<signal.h>intmain(){structsigactionnewact,oldact;newact.sa_handler=SIG_IGN;//设置信号忽略,也可以设置为处理函数sigemptyset(&newact.sa_mask);newact.sa_flags=0;intcount=0;pid_tpid=0;sigaction(SIGINT,&newact,&oldact);//原始的备份到oldact,为后续的处理恢复pid=fork();if(pid==0){while(1){printf("childexec...n");sleep(1);}return0;}while(1){if(count++>3){sigaction(SIGINT,&oldact,NULL);//恢复父进程信号处理方式kill(pid,SIGKILL);//父进程发信号给子进程}printf("fatherexec...n");sleep(1);}return0;}第二部分:定时器在Linux网络编程中,定时器的作用主要是管理定时任务,处理过期连接,检测超时队列等,那我们可以通过哪些方式实现定时器呢?1、利用系统API...setsockopt(socketfd,SOL_SOCKET,SO_SNDTIMEO,&timeout,len);setsockopt(socketfd,SOL_SOCKET,SO_RCVTIMEO,&timeout,len);intnumber=epoll_wait(fd,events,MAX_EVENT_NUMBER,timeout);...通过使用socket的参数,设置连接句柄的发送和接收数据超时时间,可以实现定时处理:

(1)SO_SNDTIMEO发送数据超时时间,根据timeout设置;

(2)SO_RCVTIMEO接收数据超时时间,根据timeout设置;

IO复用的参数中都带了一个timeout参数,可以设置来达到定时触发分支逻辑,比如epoll_wait;2、简单的定时器(1)启动一个线程实现定时器,具体实现如下图:主线程启动,开始执行任务,这里可以是网络收发或者其他;启动一个线程,做定时任务处理使用;主线程需要增加定时任务,可以将任务封装为task,添加到任务队列中;同时通知定时线程,队列中有任务了,这里通知机制可以是信号量或者广播方式;定时线程取出队列中任务,判断当前任务是否过期,如果过期就执行,没有过期就继续放入任务队列中,同时这里需要让线程等待队列中距离下一个周期最短的时间,继续取队列任务;(2)使用epoll_wait设置timeout,是在网络事件触发的定时器中最方便的方式,具体逻辑如下:...start_timer=...//开始执行时间while(true){intnumber=epoll_wait(epfd,events,MAX_EVENT_NUMBER,timeout);for(...){...//处理连接任务...}end_timer=...//epoll_wait返回并处理任务时间//处理定时任务,判断当前时间是否在一个timeoutif(end_timer-start_timer>timeout){//这里是伪代码,具体时间判断可以参考linux结构体...//启动线程执行定时任务逻辑...}}3、时间轮时间轮是一种高效定时器,通过类似圆盘的形式定义每个tick,定时转动圆盘,假设每次tick时间为si,一个时间轮有N个tick,那么执行转动一圈时间为N*si;

现在插入一个任务,需要to1时间周期后执行,这里就分情况处理:

(1)如果to1<N*si,则需要分配到(当前时间轮的位置+to1/si)的位置上,等待自然tick到达执行当前to1的定时任务;

(2)如果to1>N*si,则需要分配到(当前时间轮的位置+(to1%N)/si+N)的位置上,由于to1执行时间超过一轮的周期,所以需要等待多轮转动后才能执行,那如何处理呢?因此我们将每个轮的tick上挂一个链表,这个链表的节点表示到达这个tick需要执行的任务to1,这里的节点有可能是大于一个轮转动的事件周期,也可能就是当前轮时间周期内执行,我们只需要当事件到达tick时,取出链表遍历链表节点to1,判断是否是当前事件周期内执行,如果是摘除链表节点然后执行任务,如果不是则重新计算to1需要多久后执行,计算方法就和上面的一样(当前时间轮位置+((to1-链表最小的周期时间)%N)/si+N),然后将当前链表节点重新放回;事件轮4、时间堆堆的数据结构应该大家都比较熟悉了,堆是一种满足以下条件的树:堆中某个节点的值总是不大于或不小于其父节点的值;堆总是一棵完全二叉树;添加堆节点的时间复杂度O(lgn),删除节点是O(lgn),获取节点是O(1);时间堆(1)循环线程读取最小时间堆的堆顶元素;

(2)取出最小节点,判断当前事件是否过期,如果过期则继续执行,否则不处理;

(3)将最小节点对应的事件丢给执行线程执行;

这里最小时间堆节点在代码实现中可以用一个数组表示,使用完全二叉树的排列。#include<iostream>voidheapify(intarr[],intn,inti){if(i>=n)return;intmin_node=i;intlson=i*2+1;intrson=i*2+2;if(lson<n&&arr[min_node]>arr[lson]){//和左孩子比较,找到最小节点min_node=lson;}if(rson<n&&arr[min_node]>arr[rson]){//和右孩子比较,找到最小节点min_node=rson;}if(min_node!=i){swap(arr[min_node],arr[i]);heapify(arr,n,min_node);//递归处理}}voidheapSort(intarr[],intn){//反向取出最后一个节点intlastNode=n-1;intparent=(lastNode-1)/2;for(inti=parent;i>=0;i--){heapify(arr,n,i);}for(inti=n-1;i>=0;i--){swap(arr[i],arr[0]);heapify(arr,i,0);//调整

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论