Java重入函数_可重入函数与线程安全

介绍:

一组并发线程运行在同一进程上下文中,每一个线程都有自己独立的线程上下文,包括线程ID、栈、栈指针、程序计数器、条件码和通用目的寄存器。每个线程和其他线程一起共享进程上下文的其他部分,包括整个用户虚拟地址空间(由代码段、读/写数据、堆以及所有共享库的代码和数据区组成)。线程也共享打开的文件集合。当存在共享资源的时候,对资源的访问需要同步。这时候使用线程编写程序的时候,需要编写具有线程安全性属性的函数。一个函数,当且仅当被多个并发线程反复调用时,能够一直产生正确的结果,才能够被称为线程安全的,否则我们称其为非线程安全的。

可重入的特点:由于可重入函数多次调用不会出错,所以不必担心数据被破坏;

可重入函数在任何时候都可以被中断,一段时间后又可以运行,相应的数据不会丢失;

可重入函数只使用局部变量,即保存在CPU寄存器或者堆栈中,使用全局变量要加以保护;

不可重入的特点:使用malloc/free函数,malloc函数是用全局链表来管理堆栈的;

调用标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构;

可重入体内使用了静态数据结构;

常见的不可重入函数有:

printf----引用了全局变量stdout

malloc---全局内存分配表

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

线程安全与可重入:

可重入的定义源自于单线程环境。在单线程环境中,一段代码在执行中可能会被硬件中断,并转而调用中断服务程序(ISR)。在这次调用中断处理函数之前,有可能中断处理函数已经在执行。因此,任何中断处理函数都应该是可重入的。

线程安全的概念则是源自于多线程环境。起源不一样,那么他们之间也没有什么必然的关系。

面试题:

中断是嵌入式系统中重要的组成部分。新的关键字_interrupt。下面的代码就是用_interrupt关键字去定义了一个中断服务子程序(ISR),然后评论下面的代码;__interrupt double compute_area (double radius)

{

double area = PI * radius * radius;

printf("\nArea = %f", area);

return area;

}

代码错误:

1、ISR不能返回一个值。

2、ISR不能传递参数。

3、在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额外的寄存器入栈,有些处理器/编译器你就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。

4、printf()经常有重入和性能上的问题。

那么在这里就该有一个原则:

1、不要使用static变量和全局变量,坚持只用局部变量

2、如必须使用全局变量,利用互斥信号量来保护全局变量

3、获取得知哪些系统调用是可重入的,在多任务处理程序中都使用安全的系统调用

4、不调用其他任何不可重入的函数

5、谨慎使用malloc/free

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值