(转载)可重入函数(reentrant function)
(转载)http://blog.163.com/xu_jin_rong/blog/static/1491966220086775017178
由于cublog系统的缘故,将前段时间写的一篇blog文章再次贴上。
可重入函数这一概念早有接触,但一直未有系统的理解,最近阅读《APUE》信号一章时,其中讲解很到位,故总结如下。
信号作为一种软中断,能够被进程给捕获,因而也就中断进程的正常执行,转而去执行信号处理程序,最后再返回到原进程继续正常执行。然而,当进程正在执行malloc()动态内存分配时,信号产生从而转入到信号处理程序,但当信号处理程序中也用到了malloc()函数时,问题就出来了?因为malloc()通常维护一个所有已分配内存链表,当信号发生时,进程可能正在修改链表指针,这时在信号处理程序中将又一次修改链表。当然类似的情况还有不少,下文中将会谈到。
因此,在进行上层应用程序设计过程中我们就必须明确哪些函数是可重入性函数(reentrant functions)。可重入性函数通常也一定能够在信号处理程序(signal handler)中被调用。
图1 能够在信号处理程序中调用的可重入性函数(节自《APUE》)
|
accept |
fchmod |
lseek |
sendto |
stat |
|
access |
fchown |
lstat |
setgid |
symlink |
|
aio_error |
fcntl |
mkdir |
setpgid |
sysconf |
|
aio_return |
fdatasync |
mkfifo |
setsid |
tcdrain |
|
aio_suspend |
fork |
open |
setsockopt |
tcflow |
|
alarm |
fpathconf |
pathconf |
setuid |
tcflush |
|
bind |
fstat |
pause |
shutdown |
tcgetattr |
|
cfgetispeed |
fsync |
pipe |
sigaction |
tcgetpgrp |
|
cfgetospeed |
ftruncate |
poll |
sigaddset |
tcsendbreak |
|
cfsetispeed |
getegid |
posix_trace_event |
sigdelset |
tcsetattr |
|
cfsetospeed |
geteuid |
pselect |
sigemptyset |
tcsetpgrp |
|
chdir |
getgid |
raise |
sigfillset |
time |
|
chmod |
getgroups |
read |
sigismember |
timer_getoverrun |
|
chown |
getpeername |
readlink |
signal |
timer_gettime |
|
clock_gettime |
getpgrp |
recv |
sigpause |
timer_settime |
|
close |
getpid |
recvfrom |
sigpending |
times |
|
connect |
getppid |
recvmsg |
sigprocmask |
umask |
|
creat |
getsockname |
rename |
sigqueue |
uname |
|
dup |
getsockopt |
rmdir |
sigset |
unlink |
|
dup2 |
getuid |
select |
sigsuspend |
utime |
|
execle |
kill |
sem_post |
sleep |
wait |
|
execve |
link |
send |
socket |
waitpid |
|
_Exit & _exit |
listen |
sendmsg |
socketpair |
write |
纵观上表,我们可以看出,有不少系统调用函数并没有出现,换言之也就是非可重入性函数。函数不可重入的原因主要如下:
<!--[if !supportLists]-->(1) <!--[endif]-->函数使用了static静态数据结构
如:struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
struct passwd *getpwent(void);
以上3个函数都是返回一个指向passwd结构的指针,而该passwd结构通常都是函数中static变量,其内容在每次调用以上函数时都会被重写。因此,当进程主程序与信号处理程序中均调用了以上函数时,冲突就产生了。
<!--[if !supportLists]-->(2) <!--[endif]-->函数调用了malloc和free函数,正如文章最开始所提到的;
<!--[if !supportLists]-->(3) <!--[endif]-->函数为标准I/O的库函数,因为大多数的标准I/O库函数的实现都使用了global全局数据结构;
因此,若要写可重入性函数的做法通常是我们在函数中只修改局部变量,而不改变全局变量,或尽量不使用全局变量、静态static变量。
事实上,与可重入性函数(reentrant function)对应的还有可重入内核(reentrant kernel),其区别和联系在《深入理解Linux内核》上有较详细的讲解。
(转载)可重入函数(reentrant function)的更多相关文章
- 可重入函数reentrant function
可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数:而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能 ...
- Use Reentrant Functions for Safer Signal Handling(译:使用可重入函数进行更安全的信号处理)
Use Reentrant Functions for Safer Signal Handling 使用可重入函数进行更安全的信号处理 How and when to employ reentranc ...
- reentrant可重入函数
在多任务操作系统环境中,应用程序的各个任务是并发运行的,所以会经常出现多个任务“同时”调用同一个函数的情况.这里之所以在“同时” 这个词上使用了引号,是因为这个歌”同时“的含义与我们平时所说的同时不是 ...
- 函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)
最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...
- 可重入函数、线程安全、volatile
一. POSIX 中对可重入和线程安全这两个概念的定义: Reentrant Function:A function whose effect, when called by two or more ...
- STARTUP.A51详解及如何使能可重入函数
$NOMOD51 ;Ax51宏汇编器控制命令:禁止预定义的8051;------------------------------------------------------------ ...
- KEILC51可重入函数及模拟栈浅析
MARK:文章中的红色部分是个人的理解. KEILC51可重入函数及模拟栈浅析 关键字:keilc51,模拟堆栈,可重入函数调用,参数传递,C?XBP,C?ADDXBP 摘要:本文较详细的介绍了kei ...
- UNIX高级环境编程(13)信号 - 概念、signal函数、可重入函数
信号就是软中断. 信号提供了异步处理事件的一种方式.例如,用户在终端按下结束进程键,使一个进程提前终止. 1 信号的概念 每一个信号都有一个名字,它们的名字都以SIG打头.例如,每当进程调用了ab ...
- 【Linux】可重入函数和线程安全的区别与联系【转】
转自:http://blog.csdn.net/scenlyf/article/details/52074444 版权声明:本文为博主原创文章,未经博主允许不得转载. *****可重入函数 函数被不同 ...
随机推荐
- ios fixed属性bug解决方法
在内容层外面包一个div 加上样式:position:fixed;top:0px; bottom:50px;overflow:scroll; 就可以完美解决
- OpenCV学习(1)-安装(Windows)
下载安装 在这里下载.我下载了2.4.9的Windows版本.双击安装即可. 配置环境变量 配置环境变量的目的是为了让系统找到OpenCV的动态链接库.因此需要把动态链接库添加到系统环境变量PATH中 ...
- Ubuntu不卸载ibus前提下安装搜狗输入法
第一步 在命令行中输入以下行命令安装fictx框架 sudo apt-get install fcitx fcitx-config-gtk im-switch 第二步 去 http://pinyin. ...
- eclipse汉化安装
http://hi.baidu.com/rankabc/item/b07e03466550e4ce1381dac4 Eclipse汉化方法 网上搜了很多教程,步骤都不够详细,因此写一篇傻瓜版教程让新手 ...
- ps -aux
~]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 2900 852 ? Ss 11:49 ...
- jquery中onclick内$(this)指向
jquery中onclick=”fn”中$(this)所代表的对象 js方法 function qiehuan(){ var src = $(this).attr(“data”); alert($(t ...
- nginx服务器的日志太多:定期执行脚本删除
#!/bin/bash -type f -name *.log | xargs rm -f 脚本名字autodellog.sh 设置定时器(每天凌晨一点执行) [root@localhost ~]# ...
- jquery阻止事件的两种实现方式
再阻止事件冒泡的方面,jquery有两种方式: 一种是 return false;另外一种是 e.stopPropagation() html代码 <form id="form1&qu ...
- Boost.Build 简明教程
Boost.Build 简明教程 目录1. 介绍2. 构建过程3. 基本任务4. 项目管理5. 最佳实践6. 规则参考7. 特征参考 介绍 编译器和平台无关编译系统Boost.Build是一个高级编译 ...
- PHP源代码分析(第一章):Zend HashTable详解【转】
转载于http://www.phppan.com/2009/12/zend-hashtable/ 在PHP的Zend引擎中,有一个数据结构非常重要,它无处不在,是PHP数据存储的核心,各种常量.变量. ...