zoukankan      html  css  js  c++  java
  • [Linux]不可重入函数

    一、概述

    怎么会有可重入和不可重入

    在多任务系统下,中断可能在任务执行的任何时间发生;如果一个函数的执行期间被中断后,到重新恢复到断点进行执行的过程中,函数所依赖的环境没有发生改变,那么这个函数就是可重入的,否则就不可重入

    在中断前后不都要保存和恢复上下文吗,怎么会出现函数所依赖的环境发生改变了呢?

    我们知道中断时确实保存一些上下文,但是仅限于返回地址,cpu寄存器等之类的少量上下文,而函数内部使用的诸如全局或静态变量,buffer等并不在保护之列,所以如果这些值在函数被中断期间发生了改变,那么当函数回到断点继续执行时,其结果就不可预料了。

    满足下面条件之一的多数是不可重入函数:

    (1)使用了静态数据结构;

    (2)调用了malloc或free;

    (3)调用了标准I/O函数;

    (4)进行了浮点运算.

    malloc/free是不可重入的,它们使用了全局变量来指向空闲区;

    标准I/O库的很多实现都使用了全局数据结构;

    许多的处理器/编译器中,不可重入的 (浮点运算大多使用协处理器或者软件模拟来实现)。

    在信号处理程序及多线程编程时,要特别注意。

    考虑这种情况

    1) 信号处理程序A内外都调用了同一个不可重入函数B;B在执行期间被信号打断,进入A (A中调用了B),完事之后返回B被中断点继续执行,这时B函数的环境可能改变,其结果就不可预料了。

    2) 多线程共享进程内部的资源,如果两个线程A,B调用同一个不可重入函数F,A线程进入F后,线程调度,切换到B,B也执行了F,那么当再次切换到线程A时,其调用F的结果也是不可预料的。

    在信号处理程序中即使调用可重入函数也有问题要注意。作为一个通用的规则,当在信号处理程序中调用可重

    入函数时,应当在其前保存errno,并在其后恢复errno。(要了解经常被捕捉到的信号是SIGCHLD,其信号处理程序通常要调用一种wait函数,而各种wait函数都能改变errno。)

     

    二、实例

    给出一段程序,这段程序从信号处理程序my_alarm调用非可重入函数getpwnam,而my_alarm每秒被调用一次。在该程序中调用alarm函数使得每秒产生一次SIGALRM信号。

     

    #include <stdio.h>
    #include <pwd.h>
    #include <unistd.h>
    #include <string.h>
    #include <signal.h>
    
    static void my_alarm(int signo){
        struct passwd * rootptr;
    
        printf("in signal handler
    ");
        if((rootptr = getpwnam("root")) == NULL){
            fprintf(stderr, "getpwnam(root) error
    ");
        }
        alarm(1);
    }
    
    int main(void){
        struct passwd *ptr;
    
        signal(SIGALRM, my_alarm);
        alarm(1);
        for(;;){
            if((ptr = getpwnam("ives")) == NULL){
                fprintf(stderr, "getpwnam(ives) error
    ");
            }
            if(strcmp(ptr->pw_name, "ives") != 0){
                printf("return value corrupted!, pw_name = %s
    ", ptr->pw_name);
            }
        }
    }

    在大多数系统下,该代码不会正常工作,只会输出一串"in signal handler"就阻塞在那里不再运行。

     

  • 相关阅读:
    AVL树入门
    hdu 3709 Balanced Number
    跟着病毒学技术--学习WannaCry自己实现LoadLirbrary
    Win7下64位扫雷逆向以及辅助制作
    Qt使用.lib静态库和.dll动态库文件
    X64调用规范
    “热补丁”Hook,多线程下InlineHook解决方法
    x86 x64下调用约定浅析
    配置Sublime Text3编译汇编并高亮代码
    反调试技术(一)--静态反调试
  • 原文地址:https://www.cnblogs.com/yiyide266/p/10642341.html
Copyright © 2011-2022 走看看