精华内容
下载资源
问答
  • 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不少的KaTeX数学...

    调试程序时候常用printf来作为调试日志输出,方便定位问题所在位置。但最近出现一个现象程序运行过程中会出现莫名的异常死机。

    但是在死之前有个征兆,观看打印的日志,有两条信息穿插打印的现象。所以才想起来去考虑是不是printf引起的。

    在整个项目中我运行的有8个任务,而在每一个任务里面几乎都会有使用printf进行调试信息打印。所以从开始就埋下了一颗定时炸弹。只是要碰下运行,运气好的时候一切风平浪静。运气不好的时候就炸的异常到处横飞。

    在看下自己代码printf重映射的fput接口用的还是HAL_UART_Transmit 阻塞发送函数接口。这样在波特率为115200的情况下,假如打印一条200bytes的日志信息就要约等于19ms的时间。这岂不严重影响其他任务的实时性。

    所以先把fput改为非阻塞的形式,这个可以使用freertos的stream_buffer,这个可以把要发送的数据压入buffer,然后真正的发送就使用串口发送为空中断从stream_buffer一个个byte进行读取发送。这样可以保证调用printf——》到fput 就只是写stream_buffer。而不再是阻塞式调用一次printf就要等待串口完全把数据发送完。fput的代码如下:
    int fputc(int ch,FILE *file)
    {
    xStreamBufferSend(streamDebug,&ch,1,1000);
    __HAL_UART_ENABLE_IT(&DEBUG_UART,UART_FLAG_TXE);
    return ch;
    }
    本以为把阻塞改为非阻塞,这个bug解决完的美妙心情就要到来了的时候,按下了复位按键,啥?运行了还没10秒钟就又死了,甚至比之前更惨烈。

    而现在调用printf的最关键的一条代码就是xStreamBufferSend() 只能默默的打开freertos的参考手册,看下stream的详细描述。而在注意里面有下面一段话:
    在这里插入图片描述有多个不同的writers或者多个不同的readers是不安全的。也就是说在多个不同的任务中调用发送就会有可能有问题。这不正符合了我现在的场景,多个任务可能同时调用printf,相当于多个任务同时调用stream的write接口。

    stream有这个限制,那注定printf就是不可重入的了。而针对不可重入的资源最简单的办法就是用互斥量进行保护。所以我就把printf进行包装了一层取名为debug_printf:

    void debug_printf(const char *fmt, …)
    {
    va_list args;
    if(xSemaphoreTake(semDebug,portMAX_DELAY);
    va_start(args,fmt);
    vprintf(fmt,args);
    va_end(args);
    xSemaphoreGive(semDebug);
    }
    当调用debug_printf的时候先去获取信号量semDebug,如果获取不到就一直等待直到获取。该函数执行完毕以后再释放信号量。这样就充分保证了资源的独占,同时只可能有一个任务再进行debug_printf。需要说明的是vprintf底层最终还是会调用我们重映射的fput函数。

    再次上电,打印终于正常了,但是,还有但是……一波未平一波又起。开锁的时候失败了,开锁任务是一个需要实时的任务,要检测传感器转动位置。而这个异常明显是实时性得不到满足。

    仔细分析下,问题就出在printf互斥量的获取。有可能造成高优先级任务产生延时,甚至造成优先级翻转。

    假如有三个任务:任务A、任务B、任务C,优先级从低到高。现在任务A调用了debug_printf 获取了信号量,而高优先级的任务C也需要调用debug_printf,但因为获取不到信号量就会造成暂时挂起,等到任务A打印完成把信号量释放了任务C才能得以运行。这样高优先级的任务无法抢占低优先级任务而降低了实时性。如下图所示:
    在这里插入图片描述上图的是一种情况,还不算最坏的。还有可能出现优先级翻转的问题,造成延时更大。同样最低优先级任务A先运行并且调用了debug_printf获取到了信号量,而这时候任务c也需要运行并调用了debug_printf。但是因为A已经把信号量占用而无法获取到,所以暂时被挂起。任务A开始打印,在打印到一半的时候,被中等优先级的任务B给打断了(任务B不调用debug_printf所以可以打断A)。这时候A又挂起了,任务B开始运行,等到B运行完以后继续运行A。等A运行完信号量释放了,高优先任务C终于可以得到运行了。如下图所示,这时候看看任务C本来可以实时的运行的,现在却中间又穿插先运行了中优先级任务B。造成一个中优先级比高优先级任务先得到运行的优先级翻转现象。而实时性相比上图就更差了。

    并且这个延时是不可估量的,想想任务B还可能再被更高优先级的任务打断。高优先级任务C反而被一再延时执行。所以出现高优先级任务出现问题就不难理解了。
    在这里插入图片描述
    发现了问题还是要解决问题。根据分析肯定要改造一下debug_printf,同时为了实时性得到满足。我就把任务C高优级的打印LOG暂时关闭。

    而针对debug_printf中获取信号量修改为有时间限制,不再无限期等待。这样顶多出现获取不到信号量5ms超时返回少打印一条log信息,总比把任务卡出异常要好的多。改造后的debug_printf如下:

    void debug_printf(const char *fmt, …)
    {
    va_list args;
    if(xSemaphoreTake(semDebug,5)==pdFALSE)return;
    va_start(args,fmt);
    vprintf(fmt,args);
    va_end(args);
    xSemaphoreGive(semDebug);
    }

    展开全文
  • 这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,剥夺型内核中是危险的,如同一个安静的水雷...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过

     这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,可剥夺型内核中是危险的,如同一个安静的水雷。可能会被触发,也可能安然无恙。由于它运行结果的不可预期性,会使系统带来隐患。

    printf()经常有重入解释

    不可重入函数不可以在它还没有返回就再次被调用。例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不能在中断处理函数里调用printf,否则printf将会被重入。 

    函数不可重入大多数是因为在函数中引用了全局变量。例如,printf会引用全局变量stdout,malloc,free会引用全局的内存分配表。

    个人理解:如果中断发生的时候,当运行到printf的时候,假设发生了中断嵌套,而此时stdout资源被占用,所以第二个中断printf等待第一个中断的stdout资源释放,第一个中断等待第二个中断返回,造成了死锁,不知这样理解对不对。

     
      
    不可重入函数指的是该函数在被调用还没有结束以前,再次被调用可能会产生错误。可重入函数不存在这样的问题。
    不可重入函数在实现时候通常使用了全局的资源,在多线程的环境下,如果没有很好的处理数据保护和互斥访问,就会发生错误。
    常见的不可重入函数有:
    printf --------引用全局变量stdout
    malloc --------全局内存分配表
    free    --------全局内存分配表
    在unix里面通常都有加上_r后缀的同名可重入函数版本。如果实在没有,不妨在可预见的发生错误的地方尝试加上保护锁同步机制等等。



    下面引用一段别人的解释:

    这主要在多任务环境中使用,一个可重入的函数简单来说,就是:可以被中断的函数。就是说,你可以在这个函数执行的任何时候中断他的运行,在OS的调度下去执行另外一段代码而不会出现什么错误。而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等等,所以他如果被中断的话,可能出现问题,所以这类函数是不能运行在多任务环境下的。

    把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。


    其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。

    第一,不要使用全局变量。因为别的代码很可能覆盖这些变量值。

    第二,在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL来描述。

    第三,不能调用任何不可重入的函数。

    第四,谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。

    还有一些规则,都是很好理解的,总之,时刻记住一句话:保证中断是安全的!

    通俗的来讲吧:由于中断是可能随时发生的,断点位置也是无法预期的。所以必须保证每个函数都具有不被中断发生,压栈,转向ISR,弹栈后继续执行影响的稳定性。也就是说具有不会被中断影响的能力。既然有这个要求,你提供和编写的每个函数就不能拿公共的资源或者是变量来使用,因为该函数使用的同时,ISR(中断服务程序)也可那会去修改或者是获取这个资源,从而有可能使中断返回之后,这部分公用的资源已经面目全非。


    满足下列条件的函数多数是不可重入的:

    (1)函数体内使用了静态的数据结构;

    (2)函数体内调用了malloc()或者free()函数;

    (3)函数体内调用了标准I/O函数。


      下面举例加以说明。

    可重入函数

    void strcpy(char* lpszDest, char* lpszSrc)

    {

      while(*lpszDest++ = *lpszSrc++);

      *dest=0;

    }

    非可重入函数1

    char cTemp; // 全局变量

    void SwapChar1(char* lpcX, char* lpcY)

    {

      cTemp = *lpcX;  

      *lpcX = *lpcY;  

      lpcY = cTemp; // 访问了全局变量,在分享内存的多个线程中可能造成问题

    }

    非可重入函数2

    void SwapChar2(char* lpcX, char* lpcY)

    {

      static char cTemp; // 静态局部变量

      cTemp = *lpcX;  

      *lpcX = *lpcY;  

      lpcY = cTemp; // 使用了静态局部变量,在分享内存的多个线程中可能造成问题

    }

      如何写出可重入的函数?在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。

    展开全文
  • printf重入问题及解决方法

    千次阅读 2012-04-30 08:52:28
    一、可重入函数 1)什么是可重入性? 可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享。 可重入函数要么使用本地变量...

    一、可重入函数
    1)什么是可重入性?
    可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享。

    可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据。

    2)可重入函数:
    为连续的调用持有静态数据
    不返回指向静态数据的指针;所有数据都由函数的调用者提供。
    使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
    如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
    绝不调用任何不可重入函数

    3)不可重入函数:
    函数中使用了静态变量,无论是全局静态变量还是局部静态变量。
    函数返回静态变量
    函数中调用了不可重入函数
    函数体内使用了静态的数据结构
    函数体内调用了malloc()或者free()函数
    函数体内调用了其他标准I/O函数
    函数是singleton中的成员函数而且使用了不使用线程独立存储的成员变量 。
    总的来说,如果一个函数在重入条件下使用了未受保护的共享的资源,那么它是不可重入的。

    常见的不可重入函数有:
    printf --------引用全局变量stdout
    malloc --------全局内存分配表
    free    --------全局内存分配表
    在unix里面通常都有加上_r后缀的同名可重入函数版本。

     

    把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。

    二、函数编写规范
    1 :对所调用函数的错误返回码要仔细、全面地处理
      
    2 :明确函数功能,精确(而不是近似)地实现函数设计
      
    3 :编写可重入函数时,应注意局部变量的使用(如编写C/C++ 语言的可重入函数时,应使用auto 即缺省态局部变量或寄存器变量)
    说明:编写C/C++语言的可重入函数时,不应使用static局部变量,否则必须经过特殊处理,才能使函数具有可重入性。
      
    4 :编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P 、V 操作)等手段对其加以保护
    说明

    5 :在同一项目组应明确规定对接口函数参数的合法性检查应由函数的调用者负责还是由接口函数本身负责,缺省是由函数调用者负责
    说明

    6 :防止将函数的参数作为工作变量
    说明:将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
    示例:如下函数的实现就不太好。
    void sum_data( unsigned int num, int *data, int *sum )
    {
         unsigned int count;
         *sum = 0;
      
         for (count = 0; count < num; count++)
         {
             *sum   += data[count]; // sum成了工作变量,不太好。
         }
    }
    若改为如下,则更好些。
    void sum_data( unsigned int num, int *data, int *sum )
    {
         unsigned int count ;
         int sum_temp;
         sum_temp = 0;
      
         for (count = 0; count < num; count ++)
         {
             sum_temp   += data[count];
         }
      
         *sum = sum_temp;
    }
      
    7 :函数的规模尽量限制在200 行以内
    说明:不包括注释和空格行。
    8 :一个函数仅完成一件功能

    9 :为简单功能编写函数
    说明:虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。
    示例:如下语句的功能不很明显。
    value = ( a > b ) ? a : b ;
    改为如下就很清晰了。
      
    int max (int a, int b)
    {
         return ((a > b) ? a : b);
    }
      
    value = max (a, b);
      
    或改为如下。
      
    #define MAX (a, b) (((a) > (b)) ? (a) : (b))
      
    value = MAX (a, b);
      
    10:不要设计多用途面面俱到的函数
    说明:多功能集于一身的函数,很可能使函数的理解、测试、维护等变得困难。
      
    11:函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出

     

    展开全文
  • 单片机中printf函数的重映射一、源自于:大侠有话说1.如果你在学习单片机之前学过C语言,那么一定知道printf这个函数.它最最好用的功能除了打印你想要的字符到屏幕上外,还能把数字进行格式化.例如十进制的33,用十进制...

    单片机中printf函数的重映射

    一、源自于:大侠有话说

    1.如果你在学习单片机之前学过C语言,那么一定知道printf这个函数.它最最好用的功能

    除了打印你想要的字符到屏幕上外,还能把数字进行格式化.例如十进制的33,用十进制

    方式输出就是33,用十六进制的形式就输出成21,如果用字符形式输出,那就是ASCII码

    表对应的’!’.

    2. 51年代,一些人软件仿真的时候也很喜欢使用printf,但实际代码运行中,用的人则不多,因

    为别说51年代,就是用AVR的,也会觉得printf这个函数耗费的CPU资源相当可观.所以

    printf在8位单片机时代,熟悉的人的确不多.但到了ARM时代,情况则大为不同.毕竟

    ARM的处理能力和51完全不是一个级别,这使得不少人开始喜欢使用printf在实际项目

    中作为调试过程的串口输出.因为它的格式化功能实在是相当方便.

    而本例程就是教会你这么使用printf.

    3.程序把printf的输出对象设定为串口1.有一个标准的函数是必须要自己定义的,那就是

    fputc,把这个函数的功能写成串口输出一个字符.建议在串口的初始化模块中定义

    int fputc(int ch)

    {

    USART_SendData(USART1, (u8) ch);

    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

    return ch;

    }

    然后记得一点,就是MicroLib要勾上.其实大部分情况下,都建议使用MDK附带的

    MicroLib,这东西是有一定用途的.留待以后再更多地介绍.

    L3Byb3h5L2h0dHAvaW1nLm15LmNzZG4ubmV0L3VwbG9hZHMvMjAxMjEyLzE3LzEzNTU3MjkxMDlfOTU0OS5qcGc=.jpg

    以上两步做好后,还记得要包含printf的头文件:

    #include

    那么,所有工作就大功告成了,你可以尽情的尝试printf带来的便利.

    4.另外大家是否意识到一点,就是printf输出到哪,其实是由fputc函数决定的.所以如果有兴

    趣,可以改写这个fputc函数,使得其printf的对象是DX-32板上的TFT屏或者黑白屏.大家有

    兴趣的不妨试试.

    二、源自于:STM32开发板(正点原子)

    //加入以下代码,支持printf函数,而不需要选择use MicroLIB

    #if 1

    #pragma import(__use_no_semihosting)

    //标准库需要的支持函数

    struct __FILE

    {

    int handle;

    /* Whatever you require here. If the only file you are using is */

    /* standard output using printf() for debugging, no file handling */

    /* is required. */

    };

    /* FILE is typedef’ d in stdio.h. */

    FILE __stdout;

    //定义_sys_exit()以避免使用半主机模式

    _sys_exit(int x)

    {

    x = x;

    }

    //重定义fputc函数 ,串口1

    int fputc(int ch, FILE *f)

    {

    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕

    USART1->DR = (u8) ch;

    return ch;

    }

    #endif

    如果简化stm32中printf函数的使用——首先重定向

    STM32单片机极简方法 使用宏定义 代替复杂的重定向printf()函数,实现串口打印.(HAL库例程)https://blog.csdn.net/wu10188/article/details/9 ...

    关于STM32中printf函数的重定向问题

    printf函数一般是打印到终端的,stm32芯片调试中经常需要用到串口来打印调试信息,那能不能用串口实现类似windows的Console中的printf呢? 答案是肯定的,那就是printf函数的 ...

    C中printf函数的用法总结

    函数语法 stdio.h文件中的定义: /* Write formatted output to stdout. */ int printf (const char *__restrict __for ...

    C 中 关于printf 函数中度剖析

    题外话  这篇博文主要围绕printf函数分析的,主要讲解printf 使用C的可变参数机制, printf是否可重入(是否线程安全), printf函数的源码实现. 正文 1.C中可变参数机制 我们 ...

    在keil中使用printf&lpar;&rpar;函数的要点

    在keil中printf默认是向串口中发送数据的,所以,如果应用该函数,必须先初始化串口,否则可能引起死机的情况,并且在printf之前应该先将TI置位,摘抄原因如下: 1.printf函数是调用pu ...

    OpenCV探索之路(八):重映射与仿射变换

    重映射 重映射就是把一幅图像中某个位置的像素放置到另一个图片中指定位置的过程. 用一个数学公式来表示就是: 其中的 f 就是映射方式,也就说,像素点在另一个图像中的位置是由 f 来计算的. 在Open ...

    printf 函数的实现原理

    /* * ===================================================================================== * * Filen ...

    c&plus;&plus;中的函数重载、函数重写、函数重定义

    目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...

    关于在MDK中使用 printf 函数

    microlib 提供了一个有限的 stdio 子系统,它仅支持未缓冲的 stdin.stdout 和 stderr. 这样,即可使用 printf() 来显示应用程序中的诊断消息. 要使用高级 I/ ...

    随机推荐

    深入理解DOM事件类型系列第一篇——鼠标事件

    × 目录 [1]类型 [2]顺序 [3]坐标位置[4]修改键[5]相关元素[6]鼠标按键[7]滚轮事件[8]移动设备 前面的话 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备.本文 ...

    0&period; WP8&period;1学习笔记

    应用程序生命周期: 运行: 在程序NotRunning状态下点击图标,应用将处于Running状态,这会触发一个Actived事件 挂起: 在程序Running状态下, 点击返回键或win键会触发一个 ...

    mybatis转义符(转)

    第一种方法: 用了转义字符把>和

    使用loki&plus; mtail &plus; grafana &plus; prometheus server分析应用问题

    loki 是一个方便的类似prometheus 的log 系统,mtail 是一个方便的日志提取工具, 可以暴露为http 服务——支持导出prometheus metrics 环境准备 docker ...

    CentOS7 php7 安装 curl 扩展

    直接从php源码包中,使用root权限安装. 找到原先安装PHP的源码包文件(如果已经删掉需要重新下载原来版本的源码包并解压) 我的php源码包在root家目录下. cd /php-7.1.4/ext ...

    jQuery的事件处理方法

    .on()方法用来处理事件 $("li").on("click",function(){ $(this).addClass("complete&quo ...

    ACM学习历程—HDU5410 CRB and His Birthday(动态规划)

    Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son ...

    变量和数据类型&amp&semi;运算符

    变量和数据类型&运算符 变量 变量的作用:用来存储数据 变量命名的规范:字(字符串)下(_下划线)美($)人(¥) 数 (可以包括数字)骆驼 有意义(可以以字母,下划线,美元符号,人民币符号开 ...

    展开全文
  • printf 是不可重入函数

    2013-09-24 22:53:43
    中断函数必须采用可重入函数。可重入函数: 在实时系统设计中,RTOS,(real time operting system),经常会出现多个task同时调用同一个function的情况。改function必须设计为可重入函数。1.坚持使用auto局部变量,...
  • printf()经常有重入解释 ...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不能在中断处理函数里调用printf,否则printf将会被重入  函
  • 为什么不能在中断中使用printf--不可重入函数

    千次阅读 多人点赞 2019-12-16 20:07:25
    printf不能在中断中被调用的原因是它是一个不可重入函数,而在中断中要避免调用不可重入函数,首先我们先说说什么是可重入函数,什么是不可重入函数 简单说来,区分一个函数是否可重入就是看这个函数能否在未返回的...
  • printf重入问题及解决方法 标签: 数据结构工作任务语言测试unix 2012-04-30 08:52 2476人阅读 评论(0) 收藏 举报  分类: C/C++(33)  一、可重入函数  1)什么是可重入性?  ...
  • 1.zz 这个概念在嵌入式操作系统中比较重要...这主要在多任务环境中使用 CodeGo.net,一个可重入的函数简单来说,就是:可以被中断的函数。就是说,你可以在这个函数执行的任何时候中断他的运行,在OS的调度下去执行另
  • 这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,剥夺型内核中是危险的,如同一个安静的水雷...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过
  • 这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,剥夺型内核中是危险...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不能在中...
  • 类似地,printf()也被认为是不可重入的;为什么? 我知道重新进入的定义,但我想知道为什么它适用于这些功能。 是什么阻止了它们被保证可重入? 最佳答案: malloc和printf通常使用全局结构,并在内部使用基于锁的...
  • 需要自行枷锁
  • printf()重入上的用法 ...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不能在中断处理函数里调用printf,否则printf将会被重入。 函数不可重入大多数是因为
  • 重入一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。 一般浮点运算都是由专门的硬件来完成,举个例子假设有个硬件寄存器名字叫做FLOAT,...
  • 这篇文章讲了怎么使用宏替代技术结合临界区保护,解决嵌入式开发中让人头疼的不可重入标准库函数问题。
  • printf()的重入和性能上的问题 重入 重入:一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象 举个例子比如双核计算机多线程同时打印...
  • 转载: 这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,剥夺型内核中是危险的,...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,...
  • 函数的可重入和不可重入

    千次阅读 2017-04-15 18:26:26
    在早期的编程中,不可重入性对程序员并不构成威胁;函数不会有并发访问,也没有中断。在很多较老的 C 语言实现中,函数被认为是在单线程进程的环境中运行。 不过,现在,并发编程已普遍使用,您需要意识到这个缺陷...
  • 可重入函数与不可重入函数

    千次阅读 2018-01-12 15:22:00
    可重入函数与不可重入函数 在多任务系统当中,在任务执行期间捕捉到信号并对其进行处理时,进程正在执行的指令序列就被信号处理程序临时中断。如果从信号处理程序返回,则继续执行进程断点处的正常指令序列,从...
  • C语言之可重入函数 和不可重入函数

    千次阅读 2017-09-06 21:51:32
    可重入函数  在 实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果这个函数不幸被设计成为不可重入的函数的话, 那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不...
  • printf()经常有重入解释 ...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不能在中断处理函数里调用printf,否则printf将会被重入...
  • 这个概念在嵌入式操作系统中比较重要,由于存在任务的调度,它实时系统,剥夺型内核中是危险的,如同一...例如printf,malloc,free等都是不可重入函数。因为中断可能在任何时候发生,例如在printf执行过程中,因此不
  • C语言之可重入函数 && 不可重入函数

    千次阅读 2015-09-18 21:11:58
    如果这个函数不幸被设计成为不可重入的函数的话,那么不同任务调用这个函数时可能修改其他任 务调用这个函数的数据,从而导致不预料的后果。那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程...
  • liunx中可重入和不可重入函数

    千次阅读 2013-11-06 08:32:53
    可重入函数 可重入函数(即可以被中断的函数)可以被一个以上的任务调用,而不担心数据破坏。可重入函数在任何时候都可以被中断,而一段时间之后又可以恢复运行,而相应的数据不会破坏或者丢失。 可重入函数使用的...
  • 重入:一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象 举个例子比如双核计算机多线程同时打印文本就可能把文本交替的打印出来了,不是...
  • 可重入和不可重入

    2014-05-15 11:15:48
    重入一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。 一般浮点运算都是由专门的硬件来完成,举个例子假设有个硬件寄存器名字叫做FLOAT,...
  • 可重入函数 与 可重入函数

    千次阅读 2016-05-30 23:26:04
    可重入函数不可以在它还没有返回就再次被调用;该函数在被调用还没有结束之前,再次被调用,从而可能产生错误。 但是,可重入函数不存在这样的问题。 不可重入函数在实现时通常使用了全局的资源(eg. 全局变量),...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 39,581
精华内容 15,832
关键字:

printf可重入