unix 环境高级编程 信号二 可重入函数与不可重入函数

场景描述:

         在捕捉到信号时,不论进程的主控制流程执行到哪里,在未设计信号阻塞时,都会先跳到信号处理函数中去执行,从信号处理函数返回后再继续执行主控制流程,信号处理函数是一个单独的控制流程,因为它和主控制流程是异步的,两者不存在调用与被调用的关系,并且使用不同的堆栈空间,引入了信号处理函数使得一个进程具有多个控制流程,如果这些控制流程访问相同的全局资源(全局变量,硬件资源),则可能会发生冲突(导致全局变量在信号处理函数中被错误的修改等)

什么叫做重入:

         举个例子来说,在主控制流程中调用了fun()函数,但是在执行fun函数的代码段中间时,被某个信号中断,转去执行信号处理函数,在信号处理函数中又去调用fun()函数,这个叫做重入。也就是说一个函数在不同的控制流程中被同时调用,在一个控制流程中该函数尚未返回时,在另外的控制流程中该函数又被调用。  

 什么是可重入函数:

         一个函数可以被多个任务或者是多个控制流程并发的访问,而不用担心数据错误或者是执行的结果具有可预见性。典型的情况就是函数仅使用局部变量,这个时候在不同的控制流程中调用相同的函数,会在栈空间中维护局部变量而非堆空间中,这样改变的数据也仅仅是当时正在执行的函数的数据,当函数执行完之后栈空间释放,当然不会影响到另外的控制流程中的同一个函数

什么叫做不可重入函数:

         把上面的可重入函数的概念改改就行了。或者是这样理解也行:如果函数在重入条件下使用了未受保护的全局资源,则称为不可重入函数

为使我们自己写的函数成为可重入的,应该:

          不在函数中使用静态变量或者是全局变量 

          不返回全局或者是静态数据,所有的数据都由函数的调用者提供

          使用本地变量,即使使用全局变量,也使用全局变量的本地拷贝

          使用全局数据时,加锁保护

          不调用不可重入函数。

不可重入函数除了上诉相反的条件外,还有:

         函数调用了malloc()或者是free()

         函数调用了标准I/O函数(很多的标准I/O函数都以不可重入的方式使用了全局数据结构,比如隶属于进程的缓冲区)

个人认为其实可重入函数的前几条说的都是一件事,尽量不要使用堆中的数据。因为堆中的数据可以被共享。                                              

         apue中关于不可重入函数的例子举得是getpwnam()这个函数,原因在于这个函数会返回静态的数据结构。这样如果在一个控制流程进程getpwnam的调用的时候被中断执行,在另外的控制流程中调用getpwnam函数,则可能出现问题,因为静态类型的变量会在函数调用中维持其值。

        注意:本人非科班出身,学习apue纯属 个人爱好,希望多加指正不足之处。






 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值