免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4798 | 回复: 11
打印 上一主题 下一主题

关于不可再入函数不可再入的原因 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-22 09:52 |只看该作者 |倒序浏览
看<<UNIX高级环境编程>>,说不可再入的原因主要有:

1> 函数中使用全局数据结构
2> 函数中调用malloc或者free


问题:第一个原因明白,第二条原因就不明白了,请大家说说函数再入和不可再入 和 内存分配释放函数 有什么关系???

论坛徽章:
0
2 [报告]
发表于 2008-08-22 09:56 |只看该作者
malloc/free是不可重入的,它们使用了全局变量来指向空闲区;标准I/O库的很多实现都使用了全局数据结构;

论坛徽章:
0
3 [报告]
发表于 2008-08-22 09:57 |只看该作者
首先 那是不可重入。

全局结构(资源)的访问要加锁的。

论坛徽章:
0
4 [报告]
发表于 2008-08-22 10:03 |只看该作者
线程安全和可重入是两码事,
malloc   /free是线程安全的,但不是可重入的;
可重入主要体现在中断上,如果malloc的过程中发生中断(中断是锁不住的),如果在中断处理函数中有重入malloc,就会有问题

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
5 [报告]
发表于 2008-08-22 10:10 |只看该作者
像malloc这类函数,是线程安全的,会访问全局数据结构但有锁保护。然而它是异步信号不安全的,所以也是一个不可重入函数,可以想象下:某个线程调用到malloc内部时,先加锁,分配内存,更新空闲链表,此时如果执行信号处理函数且其又有一个malloc,后果很严重了,死锁!

论坛徽章:
0
6 [报告]
发表于 2008-08-22 10:47 |只看该作者
全局的变量,锁也是全局的,都导致不可重入的
malloc最明显,不太明显的有printf fopen等
所以在信号处理中调用printf 是最明显的错误,我曾经写过一段,结果发生死锁
下面是个例子


#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
void gotsig(int n)
{
    printf("b");
}

int main()
{
    struct itimerval value;
        struct sigaction sact;

    sigemptyset( &sact.sa_mask );
    sact.sa_flags = 0;
    sact.sa_handler = gotsig;
    sigaction(SIGALRM,&sact,NULL);

    value.it_interval.tv_sec = 0;
    value.it_interval.tv_usec = 1000;
    value.it_value.tv_sec = 0;
    value.it_value.tv_usec = 1000;

    setitimer(ITIMER_REAL, &value,NULL);


    while(1) {
        printf("a");
    }
}

论坛徽章:
11
技术图书徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
7 [报告]
发表于 2008-08-22 11:19 |只看该作者
原帖由 flw2 于 2008-8-22 10:47 发表
全局的变量,锁也是全局的,都导致不可重入的
malloc最明显,不太明显的有printf fopen等
所以在信号处理中调用printf 是最明显的错误,我曾经写过一段,结果发生死锁
下面是个例子


#include
#includ ...

呵呵,是啊,好像标准IO函数没有异步信号安全的

论坛徽章:
0
8 [报告]
发表于 2008-08-22 11:49 |只看该作者
不过我觉得第二个原因就不应该成为一个独立的原因,只是第一个原因中的例子而已。

论坛徽章:
0
9 [报告]
发表于 2008-08-22 11:57 |只看该作者
原帖由 flw2 于 2008-8-22 10:47 发表
全局的变量,锁也是全局的,都导致不可重入的
malloc最明显,不太明显的有printf fopen等
所以在信号处理中调用printf 是最明显的错误,我曾经写过一段,结果发生死锁
下面是个例子


#include
#includ ...

Mark一下,以后留意。。
以前确实在信号处理中调用过printf系列,但是从未在意后果。。汗颜啊

论坛徽章:
0
10 [报告]
发表于 2008-08-22 12:58 |只看该作者
原帖由 0vk0 于 2008-8-22 10:03 发表
线程安全和可重入是两码事,
malloc   /free是线程安全的,但不是可重入的;
可重入主要体现在中断上,如果malloc的过程中发生中断(中断是锁不住的),如果在中断处理函数中有重入malloc,就会有问题


分析得好,应该是搞嵌入式的吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP