(转载)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)的更多相关文章

  1. 可重入函数reentrant function

    可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数:而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能 ...

  2. Use Reentrant Functions for Safer Signal Handling(译:使用可重入函数进行更安全的信号处理)

    Use Reentrant Functions for Safer Signal Handling 使用可重入函数进行更安全的信号处理 How and when to employ reentranc ...

  3. reentrant可重入函数

    在多任务操作系统环境中,应用程序的各个任务是并发运行的,所以会经常出现多个任务“同时”调用同一个函数的情况.这里之所以在“同时” 这个词上使用了引号,是因为这个歌”同时“的含义与我们平时所说的同时不是 ...

  4. 函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)

    最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...

  5. 可重入函数、线程安全、volatile

    一. POSIX 中对可重入和线程安全这两个概念的定义: Reentrant Function:A function whose effect, when called by two or more  ...

  6. STARTUP.A51详解及如何使能可重入函数

    $NOMOD51       ;Ax51宏汇编器控制命令:禁止预定义的8051;------------------------------------------------------------ ...

  7. KEILC51可重入函数及模拟栈浅析

    MARK:文章中的红色部分是个人的理解. KEILC51可重入函数及模拟栈浅析 关键字:keilc51,模拟堆栈,可重入函数调用,参数传递,C?XBP,C?ADDXBP 摘要:本文较详细的介绍了kei ...

  8. UNIX高级环境编程(13)信号 - 概念、signal函数、可重入函数

    信号就是软中断. 信号提供了异步处理事件的一种方式.例如,用户在终端按下结束进程键,使一个进程提前终止.   1 信号的概念 每一个信号都有一个名字,它们的名字都以SIG打头.例如,每当进程调用了ab ...

  9. 【Linux】可重入函数和线程安全的区别与联系【转】

    转自:http://blog.csdn.net/scenlyf/article/details/52074444 版权声明:本文为博主原创文章,未经博主允许不得转载. *****可重入函数 函数被不同 ...

随机推荐

  1. 简单JavaSE数据类型入门

    新的一节学习了JavaSE,今天主要来说一下Java的数据类型及其输出,借用Xmind,可以生动形象的向大家来解释Java的数据类型: 其中数值整数型举例: public class A02{ pub ...

  2. oracle数据库TNS

    TNS是Oracle Net的一部分,专门用来管理和配置Oracle数据库和客户端连接的一个工具,在大多数情况下客户端和数据库要通讯,必须配置TNS,下面看一如何配置它吧: TNS简要介绍与应用 :O ...

  3. IOS_OC_百度地图与社交分享

    前奏. 知识点介绍 一. 导航和画线 地图画线 (理解) 二. 百度地图 集成百度地图 (掌握) POI检索 (掌握) 三. 社交分享 系统自带分享 (了解) 友盟分享 (掌握) SSO授权 (理解) ...

  4. 05_Excel操作_01_简单导入导出

    [Excel组成] 主要由四部分组成: 1.工作簿 每一个Excel文件都可以看成是一个工作簿,当打开一个Excel文件时,相当于打开了一个Excel工作簿. 2.工作表 当打开了Excel工作簿后, ...

  5. AJAX原理及优缺点

    1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax ...

  6. IOS 学习笔记 2015-04-15 Xcode 工程模板分类

    一 Application类型    我们大部分呢的开发工作都是使用Application类型的模板创建IOS程序开始的,该类型包括5个模板1 Master-Detail-Application    ...

  7. 【ADO.NET】6、SQLHelper简单封装

    using System.Data.SqlClient;using System.Configuration;引用:System.Configuration 连接字符串放到配置文件中 新建一个类,写如 ...

  8. freemaker小练习

    public class TestFreemaker extends HttpServlet{    // 负责管理FreeMarker模板的Configuration实例      private ...

  9. Unix环境高级编程学习笔记——fcntl

    写这篇文正主要是为了介绍下fcntl,并将我自己在学习过程中的一些理解写下来,不一定那么官方,也有错误,希望指正,共同进步- fcntl: 一个修改一打开文件的性质的函数.基本的格式是 int fcn ...

  10. 关于C# Winform 程序开机自动启动

    1.程序运行时调用下面方法即可. /// <summary> /// 设置开机自动启用 /// </summary> private void SetAutoStart() { ...