在哪里做网站比较好/社交媒体营销三种方式
TAILQ_INIT
/** Tail queue functions.* 尾队列的头结点初始化为空队列。*/
#define TAILQ_INIT(head) do { \(head)->tqh_first = NULL; \(head)->tqh_last = &(head)->tqh_first; \
} while (/*CONSTCOND*/0)
TAILQ_INIT
宏是一个用于初始化尾队列头部的工具,它通过将 tqh_first
设置为 NULL
并将 tqh_last
设置为指向 tqh_first
的地址,确保队列可以从空状态正确地过渡到非空状态。这个设计使用了二级指针的概念,使得尾部插入操作更为高效和直接。这种结构广泛应用于需要动态管理链表的系统编程场景中。
do { ... } while (0)
:
-
这种结构确保了宏在使用时会像一个普通的语句一样执行,而不会引起语法错误。例如,用户可以安全地在
if
语句中使用这个宏,而不会因为缺少大括号导致错误 -
(head)->tqh_first = NULL;
:- 初始化
tqh_first
为NULL
,表示队列当前没有任何元素,是空的。
- 初始化
-
(head)->tqh_last = &(head)->tqh_first;
:- 初始化
tqh_last
使其指向tqh_first
的地址。这样做的目的是为了方便在队列末尾进行插入操作。具体来说,如果队列是空的,tqh_last
会指向tqh_first
,这意味着下一次插入的元素将成为新的第一个元素
- 初始化
EVUTIL_ASSERT
#define EVUTIL_ASSERT(cond) \do { \if (EVUTIL_UNLIKELY(!(cond))) { \event_errx(EVENT_ERR_ABORT_, \"%s:%d: Assertion %s failed in %s", \__FILE__,__LINE__,#cond,__func__); \/* In case a user-supplied handler tries to */ \/* return control to us, log and abort here. */ \(void)fprintf(stderr, \"%s:%d: Assertion %s failed in %s", \__FILE__,__LINE__,#cond,__func__); \abort(); \} \} while (0)
EVUTIL_ASSERT 是一个用于断言条件的宏,在条件不满足时会中止程序运行,并打印相关的调试信息。
do { ... } while (0)
结构:
-
这是一个常见的宏包装技巧,用于确保宏在使用时能够像普通语句一样执行,不会因为缺少分号或其他语法问题导致错误。
if (EVUTIL_UNLIKELY(!(cond))) { ... }
: -
EVUTIL_UNLIKELY
是一个宏或函数,通常用于提示编译器某个条件不太可能发生,这可以帮助编译器优化代码。这里的意思是,如果条件cond
为false
(即条件不满足),则执行后续代码。
event_errx(EVENT_ERR_ABORT_, "%s:%d: Assertion %s failed in %s", __FILE__, __LINE__, #cond, __func__);
: -
event_errx
是一个函数,用于打印错误信息并终止程序。它会输出文件名(__FILE__
)、行号(__LINE__
)、断言失败的条件(#cond
),以及当前函数的名称(__func__
)。 -
#cond
是将cond
转换为字符串的预处理器操作,这样可以打印出具体的条件表达式。 -
EVENT_ERR_ABORT_
通常是一个预定义的常量,用于指示错误类型,
fprintf(stderr, "%s:%d: Assertion %s failed in %s", __FILE__, __LINE__, #cond, __func__);
: -
在调用
event_errx
后,再次使用fprintf
将相同的错误信息输出到标准错误输出(stderr
)。这是为了防止用户自定义的错误处理程序可能试图返回控制权,确保错误信息一定会被输出。
最后,调用abort()
函数立即终止程序的执行。abort()
会导致程序异常退出,并生成一个核心转储(如果系统配置允许)
void event_errx(int eval, const char *fmt, ...)
{va_list ap;// 初始化可变参数列表va_start(ap, fmt);// 使用可变参数列表将格式化的错误信息输出到日志event_logv_(EVENT_LOG_ERR, NULL, fmt, ap);va_end(ap);// 结束可变参数处理// 退出程序并返回指定的错误码event_exit(eval);
}
该函数是可变参函数,相关注解见: [[可变参数]]
voidevent_logv_(int severity, const char *errstr, const char *fmt, va_list ap){char buf[1024];size_t len;if (severity == EVENT_LOG_DEBUG && !event_debug_get_logging_mask_())return;if (fmt != NULL)evutil_vsnprintf(buf, sizeof(buf), fmt, ap);elsebuf[0] = '\0';if (errstr) {len = strlen(buf);if (len < sizeof(buf) - 3) {evutil_snprintf(buf + len, sizeof(buf) - len, ": %s", errstr);}}event_log(severity, buf);}
EVBASE_ACQUIRE_LOCK N_ACTIVE_CALLBACKS
/** Lock an event_base, if it is set up for locking. Acquires the lockin the base structure whose field is named 'lockvar'. */
#define EVBASE_ACQUIRE_LOCK(base, lockvar) do { \EVLOCK_LOCK((base)->lockvar, 0); \} while (0)
#define N_ACTIVE_CALLBACKS(base) \((base)->event_count_active) //最大事件数量
/** Largest number of priorities that Libevent can support. */
#define EVENT_MAX_PRIORITIES 256
/**Set the number of different event prioritiesBy default Libevent schedules all active events with the same priority.However, some time it is desirable to process some events with a higherpriority than others. For that reason, Libevent supports strict priorityqueues. Active events with a lower priority are always processed beforeevents with a higher priority.The number of different priorities can be set initially with theevent_base_priority_init() function. This function should be calledbefore the first call to event_base_dispatch(). Theevent_priority_set() function can be used to assign a priority to anevent. By default, Libevent assigns the middle priority to all eventsunless their priority is explicitly set.Note that urgent-priority events can starve less-urgent events: afterrunning all urgent-priority callbacks, Libevent checks for more urgentevents again, before running less-urgent events. Less-urgent eventswill not have their callbacks run until there are no events more urgentthan them that want to be active.@param eb the event_base structure returned by event_base_new()@param npriorities the maximum number of priorities@return 0 if successful, or -1 if an error occurred@see event_priority_set()
TAILQ_ENTRY
//通过使用 TAILQ_ENTRY 宏,可以为指定的数据类型创建一个双向链表的入口和出口结构体,方便在链表中进行插入、删除和遍历等操作。
#define _TAILQ_ENTRY(type, qual) \
struct { \qual type *tqe_next; /* next element */ \qual type *qual *tqe_prev; /* address of previous next element */\
}
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
qual
用于指定链表结构体成员的修饰符(它可以是 const
、volatile
或其他限定符。)
-
tqe_next
:指向链表中下一个元素的指针。 -
tqe_prev
:指向链表中上一个元素的指针的地址。这里使用了一个指向指针的指针,即二级指针,用于在删除元素时修改前一个元素的tqe_next
指针。
TAILQ_HEAD
#define TAILQ_HEAD(name, type) \
struct name { \struct type *tqh_first; /* 指向链表的第一个元素 */ \struct type **tqh_last; /* 指向链表的最后一个元素的指针的指针 */ \
}
TAILQ_HEAD
是用于定义双向链表头结构的宏,使得管理链表的操作更加简单
-
tqh_first
: 指向链表的第一个元素。对于空链表,它是NULL
。 -
tqh_last
: 指向链表的最后一个元素的指针的指针。在链表的最后一个元素中,tqh_last
指向链表中最后一个元素的指针(也就是指向该元素的指针的指针)。对于空链表,它指向&tqh_first
,即链表头结构中的tqh_first
。
EVBASE_NEED_NOTIFY
/** Return true iff we need to notify the base's main thread about changes to* its state, because it's currently running the main loop in another* thread. Requires lock. */#define EVBASE_NEED_NOTIFY(base) \
(evthread_id_fn_ != NULL && \(base)->running_loop && \(base)->th_owner_id != evthread_id_fn_())
-
evthread_id_fn_
: 一个函数指针,用于获取当前线程的 ID。它用于确定事件循环是否在另一个线程中运行。 -
(base)->running_loop
: 表示事件基础是否正在运行主事件循环。如果为true
,表示主循环正在运行中。 -
(base)->th_owner_id
: 存储主事件循环线程的 ID。这个 ID 是在事件循环开始时设置的。 -
evthread_id_fn_()
: 调用evthread_id_fn_
函数来获取当前线程的 ID。
-
evthread_id_fn_ != NULL
: 确保线程 ID 函数指针有效,这意味着线程 ID 函数已经设置并可用。 -
(base)->running_loop
: 确保事件循环确实在运行中。 -
(base)->th_owner_id != evthread_id_fn_()
: 确保当前线程的 ID 与事件循环主线程的 ID 不同,表明主循环在另一个线程中运行。
这个宏的作用是检查是否需要通知主线程关于状态的变化,因为事件基础的主线程可能在不同的线程中运行。如果条件满足(即事件循环在另一个线程中运行且当前线程不是主线程),则返回 true
,表示需要通知主线程。否则返回 false
。
EVBASE_RELEASE_LOCK EVLOCK_UNLOCK
/** Unlock an event_base, if it is set up for locking. */#define EVBASE_RELEASE_LOCK(base, lockvar) do { \
EVLOCK_UNLOCK((base)->lockvar, 0); \} while (0)
/** Release a lock */#define EVLOCK_UNLOCK(lockvar,mode) \
do { \if (lockvar) \evthread_lock_fns_.unlock(mode, lockvar); \} while (0)
-
lockvar
: 具体的锁变量。这个变量是锁的实际对象,用于加锁和解锁。 -
mode
: 解锁模式,这个参数通常用于指定解锁的方式,但在这段代码中它被设置为0
,具体模式取决于锁的实现。 -
evthread_lock_fns_.unlock
: 这是一个函数指针,指向实际的解锁函数。evthread_lock_fns_
是一个结构体,包含了各种锁操作的函数指针(例如加锁、解锁等)。 -
EVBASE_RELEASE_LOCK(base, lockvar)
: 这是一个高层次的宏,用于释放event_base
的锁。它通过调用EVLOCK_UNLOCK
实现具体的解锁操作。 -
EVLOCK_UNLOCK(lockvar, mode)
: 这是一个底层宏,实际执行解锁操作。它使用evthread_lock_fns_.unlock
函数指针来解锁。mode
参数通常用于指定解锁的详细模式,但在这段代码中,它被设置为0
。
相关文章:

libevent - Macro function
TAILQ_INIT /** Tail queue functions.* 尾队列的头结点初始化为空队列。*/ #define TAILQ_INIT(head) do { \(head)->tqh_first NULL; \(head)->tqh_last &(head)->tqh_first; \ } while (/*CONSTCOND*/0)TAILQ_INIT 宏是一个用于初始化尾队列头部…...

408算法题leetcode--第17天
101. 对称二叉树 101. 对称二叉树思路:递归,对称即两个子树的左边和右边分别一样;一个子树是左中右遍历,另一个是右中左遍历;写的时候可以分三步,确定函数参数以及返回类型,确定终止条件&#…...

机器人顶刊IEEE T-RO发布无人机动态环境高效表征成果:基于粒子的动态环境连续占有地图
摘要:本研究有效提高了动态环境中障碍物建模的精度和效率。NOKOV度量动作捕捉系统助力评估动态占用地图在速度估计方面的性能。 近日,上海交通大学、荷兰代尔夫特理工研究团队在机器人顶刊IEEE T-RO上发表题为Continuous Occupancy Mapping in Dynamic …...

spring-boot web + vue
依赖的软件 maven 1. 官网下载zip 文件,比如apache-maven-3.9.9-bin.zip 2. 解压到某个盘符,必须保证父亲目录的名字包含英文,数字,破折号(-) 3. 设置环境变量M2_HOME, 并将%M2_HOME%\bin添加到windown…...

HDFS分布式文件系统01-HDFS架构与SHELL操作
HDFS分布式文件系统 学习目标第一课时知识点1-文件系统的分类单机文件系统网络文件系统分布式文件系统 知识点2-HDFS架构知识点3-HDFS的特点知识点4-HDFS的文件读写流程知识点5-HDFS的健壮性 第二课时知识点1-HDFS的Shell介绍HDFS Shell的语法格式如下。HDFS Shell客户端命令中…...

Go语言流程控制
Go语言流程控制 1.IF-ELSE2.Switch-Caseswitch 语句Type Switch 3.select 语句4.循环语句 1.IF-ELSE Go 编程语言中 if 语句的语法如下: if 布尔表达式 {/* 在布尔表达式为 true 时执行 */ }例如: package mainimport "fmt"func main() {va…...

无人机在救灾方面的应用!
一、灾害监测与评估 实时监测与评估:无人机可以快速到达灾害现场,通过搭载的高清摄像头、红外热成像仪等设备,对灾区进行实时监测和灾情评估。根据捕捉到的受灾范围、火势大小、建筑物损坏情况等关键信息,为救援行动提供决策依据…...

面试知识点总结篇一
一、C语言和C有什么区别 C语言是面向过程,强调用函数将问题分解为多个子任务,按顺序逐步进行。数据和操作分开C则是面向对象,面向对象是一种基于对象和类的编程范式,关注如何利用对象来抽象和模拟现实世界的实体。因此引入了类&a…...

【计算机网络 - 基础问题】每日 3 题(二十五)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…...

【第十八章:Sentosa_DSML社区版-机器学习之协同过滤】
【第十八章:Sentosa_DSML社区版-机器学习之协同过滤】 1.算子介绍 协同过滤是推荐系统中常用的一种方法。该算法旨在填补用户-产品关联矩阵中缺少的项。在算法中,用户和产品都是通过一组少量的潜在因素描述,这些潜在因素可以用于预测用户-产…...
TDOA方法求二维坐标的MATLAB代码演示与讲解
引言 时间差定位(Time Difference of Arrival, TDOA)是一种用于确定信号源位置的技术,广泛应用于无线通信、声学定位等领域。通过测量信号到达多个接收器的时间差,可以计算出信号源的二维坐标。本文将通过MATLAB代码演示如何使用TDOA方法来求解二维坐标。 TDOA原理 TDOA…...

基于微信的原创音乐小程序的设计与实现+ssm论文源码调试讲解
第二章 开发工具及关键技术介绍 2.1 JAVA技术 Java主要采用CORBA技术和安全模型,可以在互联网应用的数据保护。它还提供了对EJB(Enterrise JavaBeans)的全面支持,java servlet AI,JS(java server ages&…...

基于大数据技术的颈椎病预防交流与数据分析及可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

Spring MVC中实现一个文件上传和下载功能
说到文件上传和下载,相信每个开发者都有或多或少的接触过文件上传的功能吧,文件上传和下载是我们在学习计算机网络应用常见的一个功能,主要涉及到用户和服务器之间的数据传输。 我们来对文件上传和下载功能的进行相关概述吧! 文…...

Webpack 介绍
Webpack 介绍 Date: August 29, 2024 全文概要 Webpack概念: Webpack是一个静态的模块化的打包工具,可以为现代的 JavaSript 应用程序进行打包。 1-静态:Webpack可以将代码打包成最终的静态资源 2-模块化:webpack支持各种模块…...

在Linux实时监控某个应用是否运行,未运行,执行运行命令
1、shell脚本(每隔30秒检测一次) 脚本要注意的地方是:在Nodepad编辑的时候要使用Unix(LF)格式,避免在Linux无法执行命令 #!/bin/bash# RabbitMQ进程名称(可能需要根据你的安装进行调整) RABBITMQ_PROCE…...

Serilog文档翻译系列(六) - 可用的接收器、增强器、格式化输出
01、提供的接收器 Serilog 使用接收器将日志事件以各种格式写入存储。许多接收器由更广泛的 Serilog 社区开发和支持;可以通过在 NuGet 上搜索 serilog 标签找到。 02、增强器 日志事件可以通过多种方式增强属性。通过 NuGet 提供了一些预构建的增强器ÿ…...

傅里叶级数在机器人中的应用(动力学参数辨识)
B站首发!草履虫都能看懂的【傅里叶变换】讲解,清华大学李永乐老师教你如何理解傅里叶变换,辨清美颜和变声原理,!!_哔哩哔哩_bilibiliB站首发!草履虫都能看懂的【傅里叶变换】讲解,清…...

前端框架Vue、React、Angular、Svelte对比
在对比 React、Vue.js、Angular 和 Svelte 时,除了在高层次的特性上有显著差异,它们在核心设计理念和底层实现机制上也有明显的不同。为了清晰地理解这些框架,我们可以从以下几个方面来分析它们的核心不同点和底层不同点。 1. 框架类型和设计…...

深度学习后门攻击分析与实现(二)
前言 在本系列的第一部分中,我们已经掌握了深度学习中的后门攻击的特点以及基础的攻击方式,现在我们在第二部分中首先来学习深度学习后门攻击在传统网络空间安全中的应用。然后再来分析与实现一些颇具特点的深度学习后门攻击方式。 深度学习与网络空间…...

boost 的lockfree 使用
boost 的lockfree 使用 // test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <mutex> #include <memory> #include <condition_variable> #include <…...

基于Hexo个人博客界面优化
基于Hexo个人博客界面优化 怎么搭建个人博客 选择主题 经过多个对比,选择简单一点的的yilia 1.将主题文件下载解压到 你的博客目录的 themes下 下载yilia主题文件 2.改写配置 打开你的_config.yml #theme: landscape 这是原来的,改成下面这个 theme: yil…...

vue3+ts不能将类型“Timeout”分配给类型“null”不能将类型“Timeout”分配给类型number
在设置有setTimeout() 函数时,一般是需要进行清除计时器操作的; 常用的做法是定义一个全局变量timer,在onMounted或者有需要的地方进行赋值,在onBeforeUnmount进行clear,一般在定义timer变量时,使用 numbe…...

如何给多台Linux机器设置时间同步
文章目录 1,使用chrony时间同步服务1.1 修改chrony配置文件 2,使用ntpdate服务 1,使用chrony时间同步服务 Centos7默认已安装,另外基于centos7的统信OS,中科OS也会默认安装这个。如果你机器上没有这个服务,…...

忘写return有什么现象?
使用C语言,一直觉得没有return无所谓,直到被制裁。。 参考: 非void函数缺失返回值导致crash或结果异常的分析 - 知乎 (zhihu.com) 可以分析出: 没有写return 的话,eax的内容是在预期之外的。 例如更新参考内容的解…...

大数据新视界 --大数据大厂之 Druid 实时数据分析平台在大数据中的应用
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

MySQL --基本查询(下)
文章目录 3.Update3.1将孙悟空同学的数学成绩变更为 80 分3.2将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分3.3将总成绩倒数前三的 3 位同学的数学成绩加上 30 分3.4将所有同学的语文成绩更新为原来的 2 倍 4.Delete4.1删除数据4.1.1删除孙悟空同学的考…...

vue3实现自定义主题色切换功能
目录 1.添加theme样式文件2.引入样式文件3.使用变量设置css样式4.设置主题样式5.切换方法 1.添加theme样式文件 文件内容如下: html[data-theme"light"]{--text-color: #000000;/* 写需要切换的样式 */ } html[data-theme"dark"]{--text-color…...

不懂性能测试,被面试官挂了...
性能测试旨在检查应用程序或软件在特定负载下工作时的响应性和稳定性,从而检测应用程序/软件在响应速度、可扩展性和稳定性方面是否达到预期的要求。 简而言之,性能测试目标就是为了识别并消除应用程序中的性能瓶颈。 本文将为大家详细介绍性能测试主要…...

JS逆向基础-谷歌浏览器调试技巧(详细)
概述 浏览器的调试工具在 JavaScript 逆向工程中,帮助开发者分析和理解代码执行流程、变量值及其变化,从而揭示隐藏逻辑和加密机制,为破解、修改或复现代码提供重要支持。 调试面板详解 谷歌浏览器的调试面板概览: 顶部操作栏 …...