一、概述

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

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

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

我们知道中断时确实保存一些上下文,但是仅限于返回地址,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\n");
if((rootptr = getpwnam("root")) == NULL){
fprintf(stderr, "getpwnam(root) error\n");
}
alarm();
} int main(void){
struct passwd *ptr; signal(SIGALRM, my_alarm);
alarm();
for(;;){
if((ptr = getpwnam("ives")) == NULL){
fprintf(stderr, "getpwnam(ives) error\n");
}
if(strcmp(ptr->pw_name, "ives") != ){
printf("return value corrupted!, pw_name = %s\n", ptr->pw_name);
}
}
}

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

[Linux]不可重入函数的更多相关文章

  1. linux: 可重入函数与不可重入函数

    1. 可重入函数与线程安全 摘自 多线程和多进程的区别(小结) http://blog.csdn.net/hairetz/article/details/4281931 要确保函数线程安全,主要需要考 ...

  2. Linux可重入函数和线程安全的区别与联系(转)

    *****可重入函数 函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函数,这称为重入. 当程序运行到某一个函数的时候,可能因为硬件中断或者异常而使得在用户正在执行的代码暂时终端转而 ...

  3. linux系统编程之信号(四):alarm和可重入函数

    一,alarm() 在将可重入函数之前我们先来了解下alarm()函数使用: #include <unistd.h> unsigned int alarm(unsigned int sec ...

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

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

  5. (转载)可重入函数(reentrant function)

    (转载)http://blog.163.com/xu_jin_rong/blog/static/1491966220086775017178 由于cublog系统的缘故,将前段时间写的一篇blog文章 ...

  6. linux可重入、异步信号安全和线程安全

    一 可重入函数 当一个被捕获的信号被一个进程处理时,进程执行的普通的指令序列会被一个信号处理器暂时地中断.它首先执行该信号处理程序中的指令.如果从信号处理程序返回(例如没有调用exit或longjmp ...

  7. Linux 可重入内核

    Linux内核是可重入的,这意味着几个进程可能同时在内核模式下执行.(当然单处理器系统,在某一时间只会有一个进程执行,但许多会阻塞在内核模式)这些进程会分时共享CPU.I/O设备等系统资源,给用户的感 ...

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

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

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

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

随机推荐

  1. 图解从 URL 到网页通信原理

    前言 一.文本对话--从请求到响应 二.TCP/IP 协议族介绍 三.基于TCP/IP通信过程 四.TCP建立连接及断开(重点补充) 小结 前言 互联网的原始目的,就是为了传输文本(文本对话).那我们 ...

  2. CentOS_7下安装MySQL

    卸载旧版本MySQl: 下载MySQ: MySQl官网:https://dev.mysql.com/downloads/mysql/ 版本自选,操作系统选Linux-Generic,64位系统或者32 ...

  3. CountDownLatch类实现同步

    首先我们看一个普通的多线程代码 class MyThread implements Runnable { @Override public void run() { System.out.printl ...

  4. 2019余姚培训游记+ZJOJD2划水记

    2019余姚培训游记 突然就想写一个... 注意:以下全是胡言乱语的自high,还有很多错别字 Day 0 来的比较早,早上就到了 上午把一本小说看完了,是一个年轻作者的处女作. 我觉得我第一本书一定 ...

  5. kubernetes调度pod运行于master节点上

    应用背景: 使用kubeadm部署的kubernetes集群,其master节点默认拒绝将pod调度运行于其上的,加点官方的术语就是:master默认被赋予了一个或者多个“污点(taints)”,“污 ...

  6. MySQL架构备份之双机热备

    M--S架构:实现双机热备(AB复制) 1.可以降低master读压力 2.可以对数据库做“热备”,热备只能解决硬件master硬件故障,软件故障等重大故障问题,但无法解决人为误操作导致的逻辑故障(列 ...

  7. 第四十四篇--做一个简单的QQ登录界面

    功能:输入用户名和密码,正确,显示登录成功,为空的话,提示用户名和密码不能为空,还有记住密码功能. MainActivity.java package com.aimee.android.play.q ...

  8. js 里面的各种类型转换

    1:Object 对象在转换为 number 类型时,首先会调用 valueOf 方法,然后再调用 toString 方法,否则会抛出异常. 对象在转换为 string 类型时,首先会调用 toStr ...

  9. C语言的第一堂课

    感觉茂哥讲了很多,但是有些输入的语句还是没能记住 刚讲的都是概念,看来需要看一下表格,以及C语言的基础 有些意思还不能够理解 略显尴尬 回去把C语言书的各种概念理解一下……

  10. linux下python安装

    下载包: wget https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.gz 解压安装: tar -zvxf  Python-3.6.3. ...