C语言函数重新输入

由于使用了不受保护的系统资源(例如全局变量区,中断向量表),因此除非确保相互排斥(使用信号灯/代码的关键部分禁止中断),否则无法在多任务环境中运行等

重入函数:

没有静态数据结构不会返回指向静态数据的指针. 所有函数数据均由函数调用者提供. 使用自动变量,或通过复制全局变量来保护全局变量. 如果必须访问全局变量,请使用互斥信号来保护它们. 调用非可重入函数

不可重入函数为:

如果函数在重入条件下使用不受保护的共享资源,则该函数是不可重入的.

函数中使用静态变量,无论它是全局静态变量还是局部静态变量. 该函数返回一个静态变量. 在函数中调用非可重入函数. 函数中使用静态数据结构. 在函数中调用malloc()或free()函数. 该函数调用其他标准I / O函数. 该函数是单例中的成员函数. 并使用不使用线程独立存储的成员变量

将非可重入函数重写为可重入函数:

1. 不要使用全局变量

2. 当与硬件交互时可能发生中断时ccriticalsection对应c语言,请先关闭该中断(某些系列称为“进入/退出内核”或使用OS_ENTER_KERNAL / OS_EXIT_KERNAL来描述,这是关键部分的保护)

3. 不要调用非可重入函数

4. 小心使用堆栈,最好在使用前使用OS_ENTER_KERNAL

中断是嵌入式系统的重要组成部分,这导致许多编译器开发人员提供了扩展,该扩展允许标准C支持中断. ISR:

错误:

1,ISR没有返回值

如果它具有返回值,并返回给谁,则某种中断源将生成一个中断,并且系统将使用ISR进行处理. ISR链接到某个中断源,并且中断源的生成是随机的. 因此,ISR没有固定的调用方和固定的返回地址,因此返回值没有用.

2,ISR无法传递参数

3. 在许多编译器/处理器中,浮点数不是可重入的. 有些不允许在ISR中进行浮点运算.

4. ISR应该简短有效. 进行浮点数运算是不明智的.

5,printf是不可重入函数.

说明:

1. 浮点数: 通常,浮点操作由专用硬件执行. 例如,假设有一个名为FLOAT的硬件寄存器,用于计算和存储浮点数的中间运算结果.

假设有这样的功能

如果是第一次执行,则浮点运算的结果会暂时存储在FLOAT寄存器中,并在此时被中断,并且中断函数或其他进程也将调用fun函数,这是第二次调用的fun函数将在执行过程中破坏第一个FLOAT寄存器中的结果,因此,当返回第一个fun函数时,结果将不正确.

2,printf功能

引用全局变量stdout,它是标准输入和输出流的对象

malloc --------全局内存分配表

免费--------全局内存分配表

Unix通常具有可重入的函数版本,其名称后缀_r

这种情况发生在多任务系统中. 当在任务执行期间捕获并处理信号时,信号处理程序会暂时中断该过程正在执行的指令序列. 如果从信号处理程序返回,它将继续在过程断点处执行正常的指令序列. 从恢复到断点重新执行,函数所依赖的环境没有改变,可以说该函数是可重入的. 否则它不是可重入的.

众所周知,在进程中断期间,系统会保存并恢复进程的上下文,但是恢复的上下文仅限于少数上下文,例如返回地址,cpu寄存器等,以及内部诸如全局或静态变量,缓冲区等函数. 它不受保护,因此如果在函数中断期间这些值发生变化,则当函数返回到断点以继续执行时结果将不可预测. 例如,对于malloc,例如,某个进程当前正在执行malloc以分配堆空间. 此时,程序捕获信号中断. 信号处理程序中还有一个malloc. 这将对流程环境造成损害,因为Malloc通常会为其分配的存储区维护一个链接表. 在插入和执行信号处理功能时,该进程可能正在此表上运行,并且信号处理功能的调用仅覆盖了该过程的操作,从而导致错误.

以下大多数条件是不可重入函数:

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

(2)称为malloc或free;

(3)调用标准I / O函数;标准io库的许多实现都以不可重入的方式使用全局数据结构.

(4)进行了浮点运算. 在许多处理器/编译器中,浮点运算通常是不可重入的(浮点运算通常使用协处理器或软件仿真来实现.

1)信号处理程序A在内部和外部调用相同的不可重入函数B; B在执行过程中被信号中断并进入A(在A中调用B),并在完成后返回到B的中断点以继续执行. 这时,B函数的环境可能会更改,结果是不可预测的

2)多个线程在进程内部共享资源. 如果两个线程A和B调用相同的不可重入函数F,则程A进入F之后,该线程被调度为切换到B,并且B也执行F. 再次切换到线程A时,调用F的结果也是意外的

请注意,即使在信号处理程序中调用可重入函数也存在问题. 通常,在信号处理程序中调用可重入函数时,应先保存errno,然后再保存errno. (因为每个线程只有一个errno变量,所以信号处理函数可以修改其值. 要了解经常捕获的信号是SIGCHLD,它的信号处理程序通常调用wait函数,并且可以更改所有wait函数. errno. ) / p>

可重入功能列表:

_exit(),access(),警报(),cfgetispeed(),cfgetospeed(),cfsetispeed(),cfsetospeed(),chdir(),chmod(),chown(),close(),creat() ,Dup(),dup2(),execle(),execve(),fcntl(),fork(),fpathconf(),fstat(),fsync(),getegid(),geteuid(),getgid(),getgroups) (),Getpgrp(),getpid(),getppid(),getuid(),kill(),link(),lseek(),mkdir(),mkfifo(),open(),pathconf(),pause()) ,Pipe(),raise(),read(),重命名(),rmdir(),setgid(),setpgid(),setsid()ccriticalsection对应c语言,setuid(),sigaction(),sigaddset(),sigdelset(),sigemptyset) (),Sigfillset(),sigismember(),signal(),sigpending(),sigprocmask(),sigsuspend(),sleep(),stat(),sysconf(),tcdrain(),tcflow(),tcflush() ,Tcgetattr(),t cgetpgrp(),tcsendbreak(),tcsetattr(),tcsetpgrp(),time(),times(),umask(),uname(),unlink(),utime(),wait(), waitpid(),写().

在本书的信号处理程序中调用非重入函数的示例:

#include

#include

#include

静态无效函数(int signo)

{

struct passwd * rootptr;

if(((rootptr = getpwnam(“ root”))== NULL)

{

err_sys(“ getpwnam错误”);

}

信号(SIGALRM,函数);

警报(1);

}

int main(int argc,char ** argv)

{

信号(SIGALRM,函数);

警报(1);

对于(;;)

{

if(((ptr = getpwnam(“ sar”))== NULL)

{

err_sys(“ getpwnam错误”);

}

}

返回0;

}

给SIGALRM信号,然后设置一个计时器. 在for函数的执行过程中的某个时刻,也许相应的信号在getpwnam函数的运行过程中被中断,进入信号处理函数func,并在运行期间再次接收. 很容易遇到意想不到的问题.

================================================ ==== ==================================

不可重入函数在返回之前不能再次调用. 例如,printf,malloc,free等是不可重入的函数. 因为中断可能随时发生,例如在执行printf期间,您不能在中断处理程序中调用printf,否则将重新输入printf.

大多数函数都不是可重入的,因为在函数中引用了全局变量. 例如,printf将引用全局变量stdout,malloc,并自由引用全局内存分配表.

个人理解: 如果发生中断,则在运行至printf时,假定发生了中断嵌套,并且此时已占用stdout资源,因此第二个中断printf等待第一个中断stdout资源的释放. 中断正在等待第二个中断返回,从而导致死锁. 我不知道这是否正确.

非重入函数表示如果在调用函数之前再次调用该函数,则可能会产生错误. 可重入函数不存在此问题.

非重入函数通常在实现时使用全局资源. 在多线程环境中,如果不能很好地处理数据保护和互斥访问,则会发生错误.

常见的不可重入功能为:

printf --------参考全局变量stdout

malloc --------全局内存分配表

免费--------全局内存分配表

在Unix中,通常存在带有_r后缀的同名重入函数版本. 如果没有,请尝试在可预见的地方添加保护锁同步机制等.

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/jisuanjixue/article-150757-1.html

c语言 重新输入,C语言函数重新输入相关推荐

  1. ACMNO.25 C语言-间隔输出 写一函数,输入一个四位数字,要求输出这四个数字字符,但每两个数字间空格。如输入1990,应输出1 9 9 0。 输入 一个四位数 输出 增加空格输出

    题目描述 写一函数,输入一个四位数字,要求输出这四个数字字符,但每两个数字间空格.如输入1990,应输出"1 9 9 0". 输入 一个四位数 输出 增加空格输出 样例输入 199 ...

  2. c语言16进制按10进制输出,C语言编程:写一个函数,输入一个16进制数,输出相应的10进制数。...

    满意答案 chengexin 2013.05.27 采纳率:59%    等级:11 已帮助:10599人 #include #include #include #define N 1000 char ...

  3. matlab提示用户输入参数,调用函数显示输入参数不足

    问题描述.png (29.7 KB, 下载次数: 1) 2015-1-27 09:34 上传 %Gauss-Newton算法实现如下 function[x,minf] = GN(f,x0,var,ep ...

  4. ACMNO.41C语言-数字调序 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数,见图。写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数

    题目描述 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成前面m个数,见图. 写一函数:实现以上功能,在主函数中输入n个数和输出调整后的n个数. 输入 输入数据的个数n n个整数 移动的位置m ...

  5. ACMNO.37 C语言-数字交换 输入10个整数,将其中最小的数与第一个数对换,然后把最大的数与最后一个数对换。写三个函数; ①输入10个数;②进行处理;③输出10个数。

    题目描述 输入10个整数,将其中最小的数与第一个数对换,然后把最大的数与最后一个数对换. 写三个函数: ①输入10个数:②进行处理:③输出10个数. 输入 10个整数 输出 整理后的十个数,每个数后跟 ...

  6. ACMNO.26 C语言-字符统计2 编写一函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其它字符的个数,在主函数中输入字符串以及输出上述结果。 只要结果,别输出什么提示信息。

    题目描述 编写一函数,由实参传来一个字符串,统计此字符串中字母.数字.空格和其它字符的个数, 在主函数中输入字符串以及输出上述结果. 只要结果,别输出什么提示信息. 输入 一行字符串 输出 统计数据, ...

  7. scanf 接收 空格 输入_【C语言】- printf 和scanf 函数详解!

    一.printf函数 这是在stdio.h中声明的一个函数,因此使用前必须加入#include <stdio.h>,使用它可以向标准输出设备(比如屏幕)输出数据. 1.用法 1> p ...

  8. linux中c语言kbhit函数用法,C语言判断用户是否输入-非阻塞函数kbhit

    一.基础研究 要从地址读取数据,肯定是要定义一个指针变量p,用它来实现变换地址和取值的功能.另外程序是当两个条件中的某一个出现时才停止,所以应该用while~do循环语句循环输出n和d,并用while ...

  9. C语言编程>第十周 ⑦ 请编写函数fun,该函数的功能是:统计一行字符串中单词的个数,作为函数值返回。一行字符串在主函数中输入,规定所有单词由小写字母组成,单词之间由若干个空格隔开,一行……

    例题:请编写函数fun,该函数的功能是:统计一行字符串中单词的个数,作为函数值返回.一行字符串在主函数中输入,规定所有单词由小写字母组成,单词之间由若干个空格隔开,一行的开始和结尾都没有空格. 请勿改 ...

最新文章

  1. Java解码网站post字符串(swich case用法和乱码判断)
  2. jzoj4788-[NOIP2016提高A组模拟9.17]序列【差分,贪心】
  3. hdu2955 Robberies (动态规划之背包)
  4. android插件做动态权限,Mui本地打包笔记(四)Android自定义插件的配置(以动态申请权限为例)...
  5. xsmax无法进入dfu模式_iPhoneXSMax怎么强制重启-如何进入DFU模式
  6. 磨洋工 warm-chair attrition
  7. linux crc工具,Windows和Linux下使用MD5、SHA1、CRC32校验备份文件的完整性
  8. Android5.1 快捷开关如何添加和刷新状态
  9. python帝国cms_用python 发 帝国cms 文章
  10. 用旧手机搭建服务器并实现内网穿透不需要root(本人亲测很多次最简单的一个)
  11. 多省市出台关于区块链人才引进的计划
  12. @Controller注解的一些理解吧
  13. 人生就是一个醒悟的过程(深度好文)
  14. 多商家入驻分销平台基本功能设计
  15. 禁用U盘!隐藏盘符和禁止查看
  16. c语言define作用范围,#define的作用(C语言)
  17. 王爽汇编语言 实验8
  18. 用ffmpeg+nginx+海康威视网络摄像头rtsp在手机端和电脑端实现直播
  19. ai智能视频智能分析系统
  20. VMWare 14虚拟机下载和安装说明兼容WIN10

热门文章

  1. CDOJ1323柱爷的下凡
  2. 淘特 Flutter 流畅度优化实践
  3. HPUX 11iV3 LVM新变化
  4. picpick快捷键
  5. delphi获取外网IP
  6. LaTex如何自动生成参考文献
  7. 【威联通QNAP】TS-216折腾踩坑记录(更新于22.11.22)
  8. 【jzoj4742】【单峰】
  9. 2022P气瓶充装判断题及在线模拟考试
  10. [摘录]第一部分 掌舵领航(2)