(转载)可重入函数(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 版权声明:本文为博主原创文章,未经博主允许不得转载. *****可重入函数 函数被不同 ...
随机推荐
- Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法
Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...
- (一)JAVA使用POI操作excel
1,Poi 简介 Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能 PO ...
- IOS之沙盒(Sandbox)机制
IOS中每个App应用程序都有一个单独封闭的文件夹,这个文件夹称为沙盒,并且苹果规定,任何App都无权访问其他App的沙盒 沙盒目录通过 FOUNDATION_EXPORT NSString *NSH ...
- easyui-helloworld
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 远程mysql出现ERROR 1130 (HY000): Host '172.17.42.1' is not allowed to connect to this MySQL server
ERROR 1130: Host ***.***.***.*** is not allowed to connect to this MySQL server 说明所连接的用户帐号没有远程连接的权限, ...
- 入门2:PHP相关的名词解释
/**宝宝我英语不好,后面注释拼音 请见谅**/ 1.Linux 开源的操作系统,在服务器端用户数量非常大,很多服务器都是使用Linux系统运行的. 相对windows系统来说具有非常完善的用户权限系 ...
- skymvc文件上传支持多文件上传
skymvc文件上传支持多文件上传 支持单文件.多文件上传 可以设定 文件大小.存储目录.文件类型 //上传的文件目录 $this->upload->uploaddir="att ...
- gulp最佳实践(包含js,css,html预编译,合并,压缩,浏览器自动刷新)
gulp是基于流的自动化构建工具官方网址:http://www.gulpjs.com.cn/ 一.安装需要的模块 1.新建package.json,输入下面的内容 { "name" ...
- oracle工具 sqlplus 用户管理
可以通过system用户对普通用户解锁.alter user scott account unlock; 工具:1/ sqlplusw sqlplus 自带.调用oracle安装目录下bin目录下的e ...
- TDirectory.GetLogicalDrives获取本地逻辑驱动器
使用函数: System.IOUtils.TDirectory.GetLogicalDrives class function GetLogicalDrives: TStringDynArray; s ...