网络编程:信号、定时器、Libevent

news2025/2/4 15:53:42

1. 信号

(1)信号:由用户、系统或进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常;

可由下述条件产生:

  • 对前台进程,用户可以通过终端给它发送信号,如输入 Ctrl+C
  • 系统异常,如浮点异常等
  • 系统状态变化,如定时器到期
  • 运行 kill 命令或调用 kill 函数

1.1 信号概述

1.1.1 发送信号

一个进程给其他进程发送信号

#include <sys/types.h>
#include <signal.h>
// 成功返回 0,失败返回 -1 并设置 errno
int kill( pid_t pid, int sig );

目标进程由 pid 指定

pid取值含义
pid > 0信号发送给 PID 为 pid 的进程
pid = 0信号发送给本进程组内的其他进程
pid = -1发给除 init 进程外的所有进程,发送者需要拥有对目标进程发送信号的权限
pid < -1发给 PGID 为 -pid 的进程组的所有成员

信号值 sig 为 0,不发送任何信号(检测目标进程或进程组是否存在,这种检测方式不可靠);

errno 为 EINVAL 表示无效的信号;EPERM 该进程没有权限给目标进程发送信号;ESRCH 目标进程或进程组不存在;

1.1.2 信号处理函数
#include <signal.h>
typedef void (*__sighandler_t) ( int );

参数用来指示信号的类型,必须保证是可重入的;

#include <bits/signum.h>
#define SIG_DFL ((__sighandler_t) 0)
#define SIG_IGN ((__sighandler_t) 1)

SIG_IGN 表示忽略目标信号,SIG_DFL 表示使用信号默认处理方式,例如结束进程(Term)、忽略信号(Ign)、结束进程并生成核心转储文件(Corn)、暂停进程(Stop)、继续进程(Cont);

1.1.3 Linux 信号
信号默认行为含义
SIGHUPTerm控制终端挂起
SIGPIPETerm往读端被关闭的管道或 socket 连接中写数据
SIGURGIgnsocket 连接上接收到紧急数据
SIGALRMTerm由 alarm 或 setitimer 设置的实时闹钟超时引起
SIGCHLDIgn子进程状态发送变化(退出或暂停)
1.1.4 中断系统调用

处于阻塞状态的系统调用接收到信号,并且为该信号设置了信号处理函数,默认情况下系统调用将被中断,其返回的 errno 为 EINTR;

可以使用 sigaction 为信号设置 SA_RESTART 标志以重新启动被该信号中断的系统调用;

Linux 独有:对默认行为是 Stop 的信号,没有设置信号处理函数,也可以中断某些系统调用(如 connectepoll_wait

1.2 信号函数

1.2.1 signal系统调用

为信号设置处理函数;

#include <signal.h>
_sighandler_t signal ( int sig, _sighandler_t _handler );

成功时返回一个函数指针,指向前一次该信号处理函数的函数指针(可能是默认处理函数指针 SIG_DEF 也可能是上一次调用 signal 函数传入的函数指针)

出错时返回 SIG_ERR,设置 errno;

1.2.2 sigaction 系统调用

更健壮的设置信号处理函数

// 成功时返回 0,失败返回 -1 设置 errno
int sigaction ( int sig, const struct sigaction* act, struct sigaction* oact );

act 指定新的信号处理方式,oact 输出先前的处理方式;

1.3 信号集

sigset_t 是一个长整型数组,每一位代表一个信号,共 1024 位;

1.4 网络编程相关信号

1.4.1 SIGHUP
1.4.2 SIGHUP
1.4.3 SIGURG

(1)select异常事件检测带外数据
(2)SIGURG 信号;

2. 定时器

alarm 系统调用一次只会引起一次 SIGALRM 信号;

2.1 socket 选项 SO_RCVTIMEO 和 SO_SNDTIMEO

分别用来设置 socket 接收数据 / 发送数据超时时间,数据类型为 timeval(和 select 超时参数相同);
在这里插入图片描述

2.2 SIGALRM 信号

2.2.1 基于升序链表的定时器

定时器通常包含至少两个成员:超时时间和任务回调函数;

按照超时时间做升序排序链表;

2.2.2 处理非活动连接

管理所有长时间处于非活动状态的连接

通过alarm每隔一段时间,发送 SIGALRM 信号;
有新的连接到来时,会在 connfd 上设置定时器; 每当 connfd 上有数据可读时,会重置其定时器;
超时处理函数中会检测在升序链表中是否有定时器超时,若有,则删除其 fd 上的注册事件并关闭 fd;

2.3 IO 复用系统调用的超时参数

IO 复用系统调用都可以设置超时参数,但可能会被就绪事件触发提前返回,因此需要不断更新定时参数以反馈剩余时间;

在系统调用执行前后记录当前时间,从而获得执行该系统调用的时间;

2.4 高性能定时器

2.4.1 时间轮

循环队列 + 哈希思想(类似手表),将循环队列划分为 N 个槽,槽之间的时间间隔为 SI;

插入定时器时,插入到每个 Slot 头部;

每过 SI 时间,调用 tick(),判断当前 Slot 是否有到期的定时器,并向前走一个 Slot;

2.4.2 时间堆

用最小堆实现

将堆顶定时器的超时值作为定时间隔,一旦 tick 被调用,堆顶定时器必然到期,再从剩余的定时器中找到超时时间最小的一个,并将这段时间间隔作为下一次的定时间隔;

3. 高性能 IO 框架库

3.1 概述

在这里插入图片描述

(1)句柄与事件绑定,内核通过句柄向应用程序通知事件就绪;

在 Linux 下,IO事件对应的句柄就是文件描述符,信号事件对应的句柄就是信号值;定时器事件对应固定值;

(2)事件多路分发器;统一各系统的 IO 复用系统调用;

(3)事件处理器;实现业务逻辑;与句柄绑定;

(4)Reactor;

  • handle_events;执行事件循环,重复过程:等待事件,依次调用就绪事件对应的事件处理器;
  • register_handler;往事件多路分发器中注册事件;
  • remove_handler;删除事件多路分发器中的事件;

3.2 libevent 源码分析

event 是一个事件处理器;

(1)event_base :相当于一个 Reactor 实例;

base->evsel 表示选择的 IO 复用机制,即 selectepoll等;

(2)event_new :创建事件处理器;参数为关联的 base、事件对应句柄、事件类型、具体处理函数;称为 initialized;

(3)event_add :内部调用 event_queue_insert,将事件处理器加入到各种事件队列中,根据 ev->ev_flags 进行区分;称为 pending;

(4)event_base_dispatch / event_base_loop:执行事件循环,遍历 event_base 上注册的事件直到有事件就绪,将就绪事件加入 active 事件队列中(按优先级划分的相应队列),调用相应的事件处理器;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1328465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言之初识C语言

文章目录 前言一、什么是C语言二、第一个C语言程序三、数据类型四、变量&#xff0c;常量1、变量1.1 变量的命名1.2 变量的分类1.3 变量的使用1.4 变量的作用域和生命周期2、变量 五、字符串1. 概念2. 求解字符串的长度【strlen】3. 转义字符【含笔试题】 六、注释七、选择语句…

用C#也能做机器学习?

前言✨ 说到机器学习&#xff0c;大家可能都不陌生&#xff0c;但是用C#来做机器学习&#xff0c;可能很多人还第一次听说。其实在C#中基于ML.NET也是可以做机器学习的&#xff0c;这种方式比较适合.NET程序员在项目中集成机器学习模型&#xff0c;不太适合专门学习机器学习&a…

Grafana高可用-LDAP

一. grafana高可用 1. 迁移之前的 grafana sqlitedump.sh #!/bin/bash DB$1 TABLES$(sqlite3 $DB .tables | sed -r s/(\S)\s(\S)/\1\n\2/g | grep -v migration_log) for t in $TABLES; doecho "TRUNCATE TABLE $t;" done for t in $TABLES; doecho -e ".mode…

【Skynet 入门实战练习】事件模块 | 批处理模块 | GM 指令 | 模糊搜索

文章目录 前言事件模块批处理模块GM 指令模块模糊搜索最后 前言 本节完善了项目&#xff0c;实现了事件、批处理、模糊搜索模块、GM 指令模块。 事件模块 什么是事件模块&#xff1f;事件模块是用来在各系统之间传递事件消息的。 为什么需要事件模块&#xff1f;主要目的是…

Android笔记(二十一):Room组件实现Android应用的持久化处理

一、Room组件概述 Room是Android JetPack架构组件之一&#xff0c;是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层&#xff0c;使之实现数据访问。 &#xff08;1&#xff09;实体类&#xff08;Entity&#xff09;&#xff1a;映射并封装了数据库对应的数据表中…

[前端优化]项目优化--Lighthouse

[前端优化]项目优化--Lighthouse 前端优化的分类Lighthouse 优化工具优化维度--性能(Performance)性能指标概览白屏时间--FP首字节时间--TTFB首次输入延迟--FID累积布局偏移--CLS 性能指标分析Lighthouse的性能优化方案性能优化实战解析Serve images in next-gen formatsEnable…

Postman报:400 Bad Request

● 使用Postman发送Post请求报400&#xff0c;入参为JSON&#xff1b; 二、分析 1、Postman请求并没有请求到后台Api&#xff08;由于语法错误&#xff0c;服务器无法理解请求&#xff09;&#xff1b; 2、入参出错范围&#xff1a;cookie、header、body、form-data、x-www-f…

C# Onnx yolov8n csgo player detection

目录 效果 模型信息 项目 代码 下载 C# Onnx yolov8n csgo player detection 效果 模型信息 Model Properties ------------------------- date&#xff1a;2023-12-22T15:01:08.014205 author&#xff1a;Ultralytics task&#xff1a;detect license&#xff1a;AGPL-…

Open5GSUeRANSim3:VirtualBOX VM使用static IP并和host互通

本文档参考 https://blog.csdn.net/shuaihj/article/details/127589833 https://www.cnblogs.com/manongqingcong/articles/16659150.html https://blog.csdn.net/justlpf/article/details/132977047 VM默认使用的是自动分配的IP&#xff0c;每个VM的ip都是10.0.2.15。后续为了…

管理类联考——数学——真题篇——按知识分类——代数——数列

【等差数列 ⟹ \Longrightarrow ⟹ 通项公式&#xff1a; a n a 1 ( n − 1 ) d a m ( n − m ) d n d a 1 − d A n B a_n a_1(n-1)d a_m(n-m)dnda_1-dAnB an​a1​(n−1)dam​(n−m)dnda1​−dAnB ⟹ \Longrightarrow ⟹ A d &#xff0c; B a 1 − d Ad&#x…

HBuilderX项目配置使用uview

配置uview&#xff0c;先安装再配置 如果没有package.json文件&#xff0c;先打开终端&#xff0c;执行命令 npm init -y 然后就会生成 package.json 安装 使用npm安装uview npm install uview-ui2.0.36 安装好之后&#xff0c;可以看到package.json里面已经显示版本了 查…

中间件系列 - Redis入门到实战(实战篇)

前言 学习视频&#xff1a; 黑马程序员Redis入门到实战教程&#xff0c;深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目 本内容仅用于个人学习笔记&#xff0c;如有侵扰&#xff0c;联系删除 本章学习目标&#xff1a; 短信登录 这一块我们会使用redis…

Java_集合进阶Map实现类

一、Map集合 已经学习了Map集合的常用方法&#xff0c;以及遍历方式。 下面学习的是Map接口下面的是三个实现类HashMap、LinkedHashMap、TreeMap。实际上这三个实现类并没有什么特有方法需要我们学习&#xff0c;它们的方法就是前面学习Map的方法。这里我们主要学习它们的底层…

由浅入深走进Python异步编程【多进程】(含代码实例讲解 || multiprocessing、异步进程池、进程通信)

写在前面 从底层到第三方库&#xff0c;全面讲解python的异步编程。这节讲述的是python的多线程实现&#xff0c;纯干货&#xff0c;无概念&#xff0c;代码实例讲解。 本系列有6章左右&#xff0c;点击头像或者专栏查看更多内容&#xff0c;陆续更新&#xff0c;欢迎关注。 …

JavaWeb笔记之前端开发JQuery

一、引言 1.1 概述 jQuery是一个快速、简洁的JavaScript代码库。jQuery设计的宗旨是“Write Less&#xff0c;Do More”&#xff0c;即倡导写更少的代码&#xff0c;做更多的事情。它封装JavaScript常用的功能代码&#xff0c;提供一种简便的 JavaScript操作方式&#xff0c…

微信小程序格创校园跑腿小程序源码v1.1.64+前端

简介&#xff1a; 版本号&#xff1a;1.1.64 – 多学校版本 本次更新内容&#xff1a; 订单问题修复 &#xff08;无需上传小程序&#xff09; 版本号&#xff1a;1.1.63 – 多学校版本 本次更新内容&#xff1a; 失物招领增加内容安全接口&#xff1b; 认证增加性别选…

谷歌 | Duet AI 让洞察、聚类模型和可视化变得简单

迷失在数据的海洋 我们都经历过这样的情况&#xff1a;淹没在数据的海洋中&#xff0c;努力驾驭复杂的管道&#xff0c;感觉数据令人头晕。管理大量充满不同工具和 Google 搜索的选项卡以及花费大量时间筛选数据和代码以创建满足您需求的模型所带来的挫败感&#xff0c;真的会…

elasticsearch 与 mysql的概念对比

文档 elasticsearch是面向文档存储的&#xff0c;可以是数据库中的一条商品数据&#xff0c;一个订单信息。 文档数据会被序列化为json格式后存储在elasticsearch中。 索引(Index) 索引(index):相同类型的文档的集合映射(mapping):索引中文档的字段约束信息&#xff0c;类似…

SoapUI、Jmeter、Postman三种接口测试工具的比较分析!

前段时间忙于接口测试&#xff0c;也看了几款接口测试工具&#xff0c;简单从几个角度做了个比较&#xff0c;拿出来与诸位分享一下。本文从多个方面对接口测试的三款常用工具进行比较分析&#xff0c;以便于在特定的情况下选择最合适的工具&#xff0c;或者使用自己编写的工具…