热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

可重入函数与信号安全函数

1.从不可重入到可重入可重入指,函数被并发调用。若函数写全局变量,则不可重入,改为堆分配,则可重入。2.从可重入到信号安全信号安全指,函数A执行途中,处理信号,信号处理函

1. 从 不可重入 到 可重入

可重入指,函数被并发调用。

若函数写 全局变量,则不可重入,改为 堆分配,则可重入。


2. 从 可重入 到 信号安全

信号安全指,函数A执行途中,处理信号,信号处理函数中 又调用 函数A。

若函数使用 全局变量,则信号不安全。若改为 堆分配,也不安全,因为 malloc使用了锁,

所以函数使用 锁,则信号不安全,因为,函数执行途中已获得锁,但由于处理信号,有需要申请锁,导致死锁。


3. 怎么知道函数是否安全

可重入函数 后面 通常 加了 _r

信号安全函数 使用 man 7 signal 查看


4. 怎么避免信号导致不安全

首先 信号内使用 系统调用是安全的,所以将 信号转换为 pipe,通过监听pipe 处理信号。

应注意pipe应设置为 非阻塞,否则由于 管道满导致 写阻塞,导致死锁。


5. 示例

5.1 ngx对 strerror的处理

由于 strerror 不是 Async-Signal-Safe,所以采用预读取所有 errno 信息

static ngx_str_t ngx_unknown_error = ngx_string("Unknown error");
static ngx_str_t *ngx_sys_errlist;
static ngx_err_t ngx_first_error;
static ngx_err_t ngx_last_error;
u_char *
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{
ngx_str_t *msg;
if (err >= ngx_first_error && err msg = &ngx_sys_errlist[err - ngx_first_error];
} else {
msg = &ngx_unknown_error;
}
size = ngx_min(size, msg->len);
return ngx_cpymem(errstr, msg->data, size);
}
ngx_int_t
ngx_strerror_init(void)
{
char *msg;
u_char *p;
size_t len;
ngx_err_t err;
ngx_first_error = 0;
ngx_last_error = NGX_SYS_NERR; // errno 数量
len = (ngx_last_error - ngx_first_error) * sizeof(ngx_str_t);
ngx_sys_errlist = malloc(len);
if (ngx_sys_errlist == NULL) {
goto failed;
}
for (err = ngx_first_error; err msg = strerror(err);
if (msg == NULL) {
ngx_sys_errlist[err - ngx_first_error] = ngx_unknown_error;
continue;
}
len = ngx_strlen(msg);
p = malloc(len);
if (p == NULL) {
goto failed;
}
ngx_memcpy(p, msg, len);
ngx_sys_errlist[err - ngx_first_error].len = len;
ngx_sys_errlist[err - ngx_first_error].data = p;
}
return NGX_OK;
failed:
err = errno;
ngx_log_stderr(0, "malloc(%uz) failed (%d: %s)", len, err, strerror(err));
return NGX_ERROR;
}


推荐阅读
  • NIO 通道接口详解
    本文介绍了NIO(New Input/Output)中的通道接口及其相关概念,包括通道的基本功能、接口设计以及各类通道接口的具体用途。通过本文,读者可以深入了解NIO通道的设计原理及其在实际项目中的应用。 ... [详细]
  • 一面问题:MySQLRedisKafka线程算法mysql知道哪些存储引擎,它们的区别mysql索引在什么情况下会失效mysql在项目中的优化场景&# ... [详细]
  • Java并发编程深入探讨:对象组合与线程安全
    本文详细介绍了如何利用现有线程安全组件构建大规模并发应用程序,探讨了设计线程安全类的关键要素,并提供了多种确保线程安全的技术方案。 ... [详细]
  • 新萝卜Ghost Xp Sp3 装机版
    新萝卜GhostXpSp3装机版XLB_201305ZJB.iso大小:901457920字节MD5:EBE33B7DB119CF2D0B1D79F8F0FC22BFSHA1:0 ... [详细]
  • 氙气大灯与LED大灯亮度对比分析
    本文探讨了氙气大灯与LED大灯在亮度及性能上的差异,旨在帮助消费者做出更合适的选择。 ... [详细]
  • SonarQube自动化代码扫描的安装与集成实践
    SonarQube是一款强大的开源代码质量管理平台,支持多种编程语言。通过集成不同的开发工具和CI/CD流程,SonarQube能够提供全面的静态代码分析服务,帮助开发者早期发现并修复代码缺陷,从而提高软件质量和安全性。 ... [详细]
  • 解析EasyCVR平台国标GB28181协议下的TCP与UDP模式
    在使用EasyCVR视频融合平台过程中,用户常遇到关于端口设置的问题,尤其是TCP和UDP模式的区别。本文将详细介绍这两种模式在GB28181协议下的具体应用及差异。 ... [详细]
  • 本文探讨了Java中实现定时任务的几种常见方式,包括java.util.Timer、ScheduledExecutorService以及Spring Task,并对每种方法进行了详细的代码示例和优缺点分析。 ... [详细]
  • 并发编程中的三大缺陷:数据竞争、原子性破坏与顺序违背
    本文探讨了并发编程中常见的三种缺陷——数据竞争、原子性破坏与顺序违背,分析了它们的成因及影响,并提供了相应的解决方案。 ... [详细]
  • 解决MySQL错误2002:无法建立数据库连接
    本文详细描述了在Digital Ocean服务器上托管的多个WordPress站点突然出现数据库连接错误的情况,并提供了有效的解决方案。 ... [详细]
  • 深入解析:主流开源分布式文件系统综述
    本文详细探讨了几款主流的开源分布式文件系统,包括HDFS、MooseFS、Lustre、GlusterFS和CephFS,重点分析了它们的元数据管理和数据一致性机制,旨在为读者提供深入的技术见解。 ... [详细]
  • 《Java 并发编程的艺术》第三章学习笔记
    本笔记整理了《Java 并发编程的艺术》第三章的内容,包括关键概念、思维导图和实用技巧,旨在帮助读者更好地理解和掌握Java并发编程的核心知识。 ... [详细]
  • 本文探讨了MySQL慢查询日志对系统性能的具体影响,以及如何利用这些日志来定位和优化执行效率低下的SQL语句。慢查询日志记录了所有超出设定时间阈值的SQL操作,这对于诊断和提升数据库性能至关重要。 ... [详细]
  • 深入理解Java中的阻塞队列BlockingQueue
    本文详细介绍了Java并发编程中的重要组件——阻塞队列(BlockingQueue),探讨了其工作原理、主要特性及常见用法,特别是在处理高并发场景下的应用。 ... [详细]
  • IntelliJ IDEA 配置详解及优化建议
    本文详细解析了 IntelliJ IDEA 的 JVM 参数配置,包括如何优化多核 CPU 性能、调整堆内存大小以及选择合适的垃圾回收器,以提升开发效率和系统响应速度。 ... [详细]
author-avatar
-林之涵_396
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有