vps网站目录是灰色的西安做推广网站设计

news/2025/9/23 21:42:22/文章来源:
vps网站目录是灰色的,西安做推广网站设计,展厅设计图片,网站后台上传文章为什么不显示概述 libevent的event#xff0c;event_callback#xff0c;event_base除了可以用来支持套接字的自动和手动分发#xff0c;也可用来支持定时机制#xff0c;信号处理#xff0e;这里#xff0c;我们补充对定时机制#xff0c;信号处理的分析#xff0e; libevent中的…概述 libevent的eventevent_callbackevent_base除了可以用来支持套接字的自动和手动分发也可用来支持定时机制信号处理这里我们补充对定时机制信号处理的分析 libevent中的通信对象集成了对流量控制的支持我们这里补充对通信对象流量控制的分析 libevent中的定时机制 1.概述 前面我们分析eventevent_callbackevent_base时立足于服务于套接字的event来展开分析的 libevent中的event既可以用于支持对套接字的自动分法手动分发也可用于支持定时机制还可用于支持信号处理 这一部分立足于支持定时机制来分析libevent中eventevent_callbackevent_base 2. event对于定时支持 struct event {struct event_callback ev_evcallback;union {TAILQ_ENTRY(event) ev_next_with_common_timeout;size_t min_heap_idx;} ev_timeout_pos;evutil_socket_t ev_fd;short ev_events;short ev_res; struct event_base *ev_base;union {struct {LIST_ENTRY (event) ev_io_next;struct timeval ev_timeout;// 当服务于持续性超时event时这里存储超时间隔} ev_io;struct {LIST_ENTRY (event) ev_signal_next;short ev_ncalls;short *ev_pncalls;} ev_signal;} ev_;struct timeval ev_timeout;// 服务于超时event时这里存储下个超时时间点 };我们之前已经从服务于套接字事件分发的角度介绍过eventevent_base及其各个字段含义这里我们立足与服务于定时机制介绍相关字段含义 (1). ev_evcallback服务于定时机制时同样借助ev_evcallback指定事件被分发时的处理信息 (2). ev_timeout_posevent服务于定时机制时需加入到event_base相应结构中 event_base为服务于定时的event准备了两类可选结构通用结构堆 被放置于堆结构时这里存储在堆内索引 被放置于通用结构时由于位于同一通用结构内各个event基于链表连接这里用于构建链接信息 (3). ev_fd event_base对指定event支持其服务于三种类型信号处理套接字事件分发定时机制 其中套接字事件分发与定时机制可同时存在于一个event身上 某个event同时服务于套接字事件分发定时机制时ev_fd用于存储套接字描述符 某个event独立服务于定时机制时ev_fd应设置为-1 (4). ev_events 某个event同时服务于套接字事件分发定时机制时ev_events用于存储感兴趣的套接字事件类型 某个event独立服务于定时机制时ev_events应设置为0 (5). ev_res 若一个服务于定时机制的event因为超时而被分发ev_res用于存储分发原因超时对应EV_TIMEOUT (6). ev_base 存储关联到的event_base对象指针 (7). ev_ 当服务于定时机制下且event属于持久性event此时ev_io.ev_timeout用来存储超时间隔 如何理解持久性event a. 持久性event a.1. 初次添加到event_base后从添加时间点或指定时间点开始直到达到超时间隔期间该event未被分发时会被自动分发一次分发原因将是超时 a.2. 每次event被分发即将执行其回调处理前依据当前时间点结合超时间隔计算下一次超时时间点并再次注册到event_base b. 非持久性event b.1. 初次添加到event_base后从添加时间点或指定时间点开始直到达到超时间隔期间该event未被分发时会被自动分发一次分发原因将是超时若在此期间因为其他原因得到分发分发处理前此event会自动从event_base移除这样后续不会再被event_base分发了 实现上服务于超时的event因为超时被分发时会自动从event_base移除在服务于超时的event即将被回调处理前判断若是持久性的会重新计算下个超时时间点并再次添加到event_base 作为对比服务于套接字的event因为套接字事件被分发时不会从event_base移除但在event即将被回调处理前判断若是非持久性的会将此event从event_base移除 (8). ev_timeout 服务于定时机制时用于存储此event将发生超时的超时时间点信息 3.event_callback对定时机制的支持 我们从支持定时机制角度分析其各个字段 struct event_callback {TAILQ_ENTRY(event_callback) evcb_active_next;short evcb_flags;ev_uint8_t evcb_pri; /* smaller numbers are higher priority */ev_uint8_t evcb_closure;/* allows us to adopt for different types of events */union {void (*evcb_callback)(evutil_socket_t, short, void *);void (*evcb_selfcb)(struct event_callback *, void *);void (*evcb_evfinalize)(struct event *, void *);void (*evcb_cbfinalize)(struct event_callback *, void *);} evcb_cb_union;void *evcb_arg; };(1). evcb_active_next 用于将分发的event_callback组织在链表结构 (2). evcb_flags 当此event_callback依附的event被插入服务于定时的堆结构或通用结构后将包含EVLIST_TIMEOUT (3). evcb_pri 特权级 (4). evcb_closure 当此event_callback依附的event服务于定时机制时依据是否是持久的event 对持久的eventevcb_closure为EV_CLOSURE_EVENT相应的evcb_cb_union为evcb_callback 对非持久的eventevcb_closure为EV_CLOSURE_EVENT_PERSIST相应的evcb_cb_union为evcb_callback (5). evcb_cb_union 参考上述 (6). evcb_arg 自定义回调参数 3.event_base对定时支持 (1). 提供通用结构堆结构来容纳服务于定时的event 放置在通用结构的一组event依赖一个内部的放置在堆结构的event实现分发处理 (2). 对放置在通用结构的event 其ev_timeout结构中tv_usec结构符合如下结构 高4比特位为tag固定为0x5 中间8比特位用作索引 低20位为实际数值 对持久的超时event其用于时间间隔的ev_.ev_io.ev_timeout也是如此结构 (3). event_base的事件循环会在每次io复用器分发后依据当前时间点对超时的各个event执行分发处理每次事件循环进入io阻塞等待前也会保证最大等待时间不会超过当前时间点距离最近一个会超时event超时时间点的间隔 4.io复用器对定时支持 io复用器在支持timerfd的情况下允许利用timefd而非epoll_wait的超时参数的方式实现阻塞等待的超时唤醒仅仅较新的linux内核支持此特性 libevent中的信号机制 1.概述 前面我们分析eventevent_callbackevent_base时立足于服务于套接字的event来展开分析的 libevent中的event既可以用于支持对套接字的自动分法手动分发也可用于支持定时机制还可用于支持信号处理 这一部分立足于支持信号机制来分析libevent中eventevent_callbackevent_base 2.服务于信号处理的event struct event {struct event_callback ev_evcallback;/* for managing timeouts */union {TAILQ_ENTRY(event) ev_next_with_common_timeout;size_t min_heap_idx;} ev_timeout_pos;evutil_socket_t ev_fd;short ev_events;short ev_res; /* result passed to event callback */struct event_base *ev_base;union {/* used for io events */struct {LIST_ENTRY (event) ev_io_next;struct timeval ev_timeout;} ev_io;/* used by signal events */struct {LIST_ENTRY (event) ev_signal_next;short ev_ncalls;/* Allows deletes in callback */short *ev_pncalls;} ev_signal;} ev_;struct timeval ev_timeout; };我们从信号处理视角分析各个字段 (1). ev_evcallback 包含回调处理信息 (2). ev_timeout_pos 服务于定时分发时存储所在结构内位置信息 (3). ev_fd 服务于信号处理时这里存储要处理的信号编号 (4). ev_events 服务于信号处理时必然包含EV_SIGNAL类似套接字event信号处理event也支持持久非持久概念对持久的event必然包含EV_PERSIST 对非持久的服务于信号处理的event因为信号产生被分发后即从event_base移除 对持久的服务于信号处理的event信号产生被分发后不会从event_base移除除非显式请求 (5). ev_res 服务于信号处理的event因为信号产生而被分发时这里包含EV_SIGNAL (6). ev_base 指向关联到的event_base (7). ev_ ev_signal中各个字段含义如下 a. ev_signal_next 类似套接字event服务于同一个信号编号的多个event通过链式结构关联在一起ev_signal_next用于构成链式结构 b. ev_ncalls 信号event被分发时允许设置一次分发时回调处理执行多次这里记录回调处理要执行的次数 c. ev_pncalls 这里安排这个指针的意义在于 在信号event的回调处理进行中让ev_pncalls指向ev_ncalls如果再次期间另一个用户将此event从event_base移除 移除时会通过ev_pncalls设置其指向变量为0从而使得当前信号处理回调可以尽快结束 4.event_base事件循环对信号处理的支持 struct event_base {const struct eventop *evsigsel;struct evsig_info sig;struct event_signal_map sigmap; };我们立足于服务于信号处理的角度截取event_base中相关字段并分析其含义 (1). evsigsel 套接字event的自动分发依赖io复用器信号event的分发也有自己的复用器来提供支持 (2). sig struct evsig_info {struct event ev_signal;evutil_socket_t ev_signal_pair[2];int ev_signal_added;int ev_n_signals_added; #ifdef EVENT__HAVE_SIGACTIONstruct sigaction **sh_old; #elseev_sighandler_t **sh_old; #endifint sh_old_max; };这个结构来为event_base实现信号处理提供支持其各个字段含义如下 a. ev_signalev_signal_pair 我们需要一个独立的event来帮助实现信号event的分发 在event_base的初始化阶段会创建一个pipe得到两个套接字并执行如下初始化 event_assign(base-sig.ev_signal, base, base-sig.ev_signal_pair[0], EV_READ | EV_PERSIST, evsig_cb, base); static void evsig_cb(evutil_socket_t fd, short what, void *arg) {static char signals[1024];ev_ssize_t n;int i;int ncaught[NSIG];struct event_base *base;base arg;memset(ncaught, 0, sizeof(ncaught));while (1) { #ifdef _WIN32n recv(fd, signals, sizeof(signals), 0); #elsen read(fd, signals, sizeof(signals));// 读取pipe套接字数据 #endifif (n -1) {int err evutil_socket_geterror(fd);if (! EVUTIL_ERR_RW_RETRIABLE(err))event_sock_err(1, fd, %s: recv, __func__);// 异常break;// 表示已经读取干净} else if (n 0) {break;// 表示pipe套接字被关闭了}// 对读取内容逐个字节分析for (i 0; i n; i) {ev_uint8_t sig signals[i];if (sig NSIG)ncaught[sig];// 每个字节代表一个信号编号}}EVBASE_ACQUIRE_LOCK(base, th_base_lock);for (i 0; i NSIG; i) {// 允许特定信号的event被分发时分发中执行多次回调处理if (ncaught[i])evmap_signal_active_(base, i, ncaught[i]);// 实现信号event分发}EVBASE_RELEASE_LOCK(base, th_base_lock); }这样得到的效果时若我们向使得某个信号编号下的各个event得到分发处理我们只需向base-sig.ev_signal_pair[0]套接字写入信号编号即可 b. ev_signal_added 非0时表示依附的event_base上至少注册了一个服务于信号处理的event c. ev_n_signals_added 记录依附的event_base上注册的服务于信号处理的event的数量 d. sh_oldsh_old_max 当我们向event_base注册服务于某个信号编号的event时会通过服务于信号处理的复用器执行信号处理函数安装安装时我们通过sh_old来记录此信号编号安装前的信号处理信息这样当此信号编号的最后一个event从event_base移除时我们需要借助sh_old中的信号处理信息来恢复 5.服务于信号处理的复用器 // 专门服务于信号分发的复用器 static const struct eventop evsigops {signal,NULL,evsig_add,evsig_del,NULL,NULL,0, 0, 0 };当我们最初向event_base添加某个信号编号的event时将执行一次evsig_add当我们将某个信号编号的最后一个event从event_base移除时将执行一次evsig_del a. evsig_add // 代表开始监控某个信号 static int evsig_add(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p) {struct evsig_info *sig base-sig;(void)p;EVUTIL_ASSERT(evsignal 0 evsignal NSIG);EVSIGBASE_LOCK();// 这意味着至少两个event_base各自在监控信号eventif (evsig_base ! base evsig_base_n_signals_added) {event_warnx(Added a signal to event base %p with signals already added to event_base %p. Only one can have signals at a time with the %s backend. The base with the most recently added signal or the most recent event_base_loop() call gets preference; do not rely on this behavior in future Libevent versions.,base, evsig_base, base-evsel-name);}// 通过静态结构记录最近负责信号event监控的event_base// 及其上监控的信号数目evsig_base base;evsig_base_n_signals_added sig-ev_n_signals_added;// 通过pipe的套接字实现分发通知evsig_base_fd base-sig.ev_signal_pair[1];EVSIGBASE_UNLOCK();event_debug((%s: %d: changing signal handler, __func__, (int)evsignal));// 信号处理设置if (evsig_set_handler_(base, (int)evsignal, evsig_handler) -1) {goto err;}if (!sig-ev_signal_added) {if (event_add_nolock_(sig-ev_signal, NULL, 0))goto err;sig-ev_signal_added 1;}return (0); err:EVSIGBASE_LOCK();--evsig_base_n_signals_added;--sig-ev_n_signals_added;EVSIGBASE_UNLOCK();return (-1); }上述过程主要为 为信号编号安装信号处理evsig_set_handler_处理中会安装信号处理同时将此信号编号之前的信息处理保存起来 这样后续此信号产生时将执行一次evsig_handler evsig_handler中则通过向evsig_base_fd写入此信号编号内容由于sig-ev_signal的作用这将引发event_base后续对此信号相关的所有event执行一次分发 b. evsig_del static int evsig_del(struct event_base *base, evutil_socket_t evsignal, short old, short events, void *p) {EVUTIL_ASSERT(evsignal 0 evsignal NSIG);event_debug((%s: EV_SOCK_FMT: restoring signal handler, __func__, EV_SOCK_ARG(evsignal)));EVSIGBASE_LOCK();--evsig_base_n_signals_added;--base-sig.ev_n_signals_added;EVSIGBASE_UNLOCK();return (evsig_restore_handler_(base, (int)evsignal)); }当某个信号编号的最后一个event从event_base移除时会执行一次evsig_del evsig_del会更新变量并借助evsig_restore_handler_恢复此信号编号之前的信号处理 6.最佳实践 因为linux多线程应用中发给应用的信号只会传递给一个线程激发一次信号处理 所以相应的借助event_base的event实现信号处理时我们应该 (1). 将服务于信号处理的event集中注册到一个event_base libevent中相应的设置了以下局部静态变量来存储此event_base及关联信息 #ifndef EVENT__DISABLE_THREAD_SUPPORT static void *evsig_base_lock NULL; #endif static struct event_base *evsig_base NULL; static int evsig_base_n_signals_added 0; static evutil_socket_t evsig_base_fd -1;libevent中通信对象的流量控制 1.流量控制初始化 流控初始化时会设置好时间点最大单次允许量速率间隔单位 2.读写操作前更新并获取允许流量 以读为例每次读时依据上次余量距离上次读取间隔速率最大单次允许量可以计算出本次操作允许量从而控制本次操作时允许读取的量进而达到流控效果 3.读写操作后再次更新允许流量 以读为例每次读后依据读取量上次余量重新计算余量在余量降低到0时候会通过移除可读事件来临时禁止后续读取操作并同时启动一个定时event在定时回调中重新计算余量在余量大于0时重新恢复可读事件并取消定时event

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

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

相关文章

网站设计与管理方向nas 做网站服务器

lucene 查询示例本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中,您将了解Lucene。 您将了解为什么这样的库很重要,然后了解Lucene中搜索的工作方式。 此外,您将学习如何将Lucene Search集成到您自己的应用程序中…

石家庄个人谁做网站网站建设的整体流程有哪些?

作者:HelloGitHub-追梦人物文中涉及的示例代码,已同步更新到 [HelloGitHub-Team 仓库](https://github.com/HelloGitHub-Team/HelloDjango-blog-tutorial) 博客文章的模型有一个 excerpt 字段,这个字段用于存储文章的摘要。目前为止&#xff…

网站正在建设 mp4vk汉化网站谁做的

(1)腾讯云申请 (2)域名控制台解析 (3)Nginx下载(crt: CA certificate Chain)

南宁网站建站wordpress 升级php版本

101. 简述如何在 Kotlin 中比较两个字符串?Kotlin 语言允许多种方法来检查两个字符串是否相等。 使用比较运算符 在 Kotlin 中, == 用于检查两个对象的结构相等性。如果两个对象具有相同的值,它将返回 true: fun main(args: Array) { val str1: String = "Hell…

云南 网站建设网站中国互联网数据平台

ThreadLocal基本原理 一、定义 ThreadLocal是java中所提供的线程本地存储机制,可以利用改机制将数据缓存在线程内部,该线程可以在任意时刻、任意方法中获取数据 二、底层原理 ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象中…

java里面的IO流分为哪几种,他们的区别是什么呢

Java IO流主要可以从两个最重要的维度进行分类:流向 和 操作的数据类型。按流向分(以内存为参照物):输入流(Input Stream): 将数据从外部(如文件、网络、键盘)读入到内存中。InputStream 和 Reader 是基类。 …

ReLU函数及它的导数

ReLU 函数 ReLU(Rectified Linear Unit,修正线性单元)是目前在深度学习中最常用的激活函数。它的数学表达式非常简单: $$f(x) = \max(0, x)$$ 这意味着当输入 $x$ 大于 0 时,输出就是 $x$ 本身;当输入 $x$ 小于或…

公司网站运营方案策划做 网络网站

0 前言 循环神经网络(Recurrent Neural Network,RNN)是一种用于处理序列数据的神经网络。相比一般的神经网络来说,他能够处理序列变化的数据。比如某个单词的意思会因为上文提到的内容不同而有不同的含义,RNN就能够很好…

网站建议公司新邵县住房和城乡建设局网站

TCP协议的报文格式 TCP协议有连接,可靠性传输,面向字节流,全双工。 他的数据格式如图: 根据他的数据格式,在这里我们只知道 16位源端口号(表示客户端这里的端口号),16位目的端口号&…

企业网站规划书实业公司网站建设

一、Znode分类 1、persistent_node 持久化节点 是默认类型,该类型节点,并不会随着客户端断开就会自动删除;zookeeper服务重启该节点也不会被删除,只有手动删除的时候才会删除;可以创建子节点; # create …

手机建站平台郴州网红景点

1、问题背景:maven使用默认settings.xml配置时,Idea基于pom.xml更新依赖时报错,有些组件下载时连接超时, 通过日志发下,去连接maven.org网站下载依赖,有时候肯定会超时。 2、解决办法:使用国外…

新开的网站建设公司如何推广专业的seo外包公司

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的字符串 s ,它的 偶数 下标处为小写英文字母,奇数 下标处为数字。 定义一个函数 shift(c, x) ,其中 c 是一个字符且 x 是一个数字,函数返回字母表中 c 后面第 x 个字符。 …

北京优质网站制作南通市建设局网站6

怎么通过手机照片制作视频?将照片做成视频并不是很难,可以直接在手机上进行操作,下面来看看是怎么操作的。方法/步骤在手机上打开清爽视频编辑器,有视频编辑、美拍美摄、电子相册、特效模板、动感视频、创意视频、动态字幕、视频变…

龙岩市官方网站网站风格类型是

python遍历实例总结python同时遍历数组的索引和值的实例你想在迭代一个序列的同时跟踪正在被处理的元素索引。获取索引内置的 enumerate() 函数可以很好的解决这个问题:>>> my_list [a, b, c]>>> for idx, val in enumerate(my_list):... print(…

手机网站特效郑州企业网站seo

原标题:刘总出席成都糖酒会:信任铸就云仓酒庄新篇章,共襄盛举展未来近日,备受瞩目的成都糖酒会盛大开幕,吸引了来自全国各地的业界精英和代表。在这场盛大的行业盛会上,云仓酒庄的刘总亲临现场。 现场&…

第一次个人编程作业-论文查重

| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience | | 这个作业要求在哪里| https://edu.cnblogs.com/campus/gdgy/Class34Grade23ComputerScience/homework/13477 | | 这…

使用Claude代码子代理生成项目特定提交消息的技术实践

本文详细介绍了如何利用Claude Code的子代理功能解决自动生成提交消息过于冗长的问题。通过创建专门的git提交消息生成代理,分析项目规范和变更内容,生成符合项目约定的简洁提交消息,提升开发效率。使用Claude代码子…

上海网站建设公司推荐合肥市住房建设局网站

全世界只有3.14 % 的人关注了爆炸吧知识今天,8岁表妹的老师给她奖励了一块大巧克力,超模君打趣她能不能分给我点,遭到残忍拒绝,超模君很愤怒,暗下决心要神不知鬼不觉地吃上表妹的巧克力。超模君趁表妹在认真做作业的时…

网站建设 前期资料dede门户网站模版

文章目录 1. 如何计算DDR带宽2. DDR data rate和DDR主频3. Mbps和Mhz4. 出题 1. 如何计算DDR带宽 计算DDR理论带宽的公式为: DDR主频 * 位宽 理论带宽其中,位宽(bit width)指的是内存总线的位宽,例如64位、128位、16bit、32bit等&#xff…