<<apue>> 可重入和线程安全

回顾

什么是可重入?
上一篇: 可重入和不可重入

线程安全函数

如果一个函数,对于多个线程来说是可重入的,那么这个函数就是线程安全的

异步信号安全

如果函数对于异步信号处理成序的重入是安全的,那么该函数就是异步信号安全的

包含关系

可重入与线程安全两个概念都关系到函数处理资源的方式。但是,他们有重大区别:

  1. 可重入函数要解决的问题是,不在函数内部使用静态或全局数据,不返回静态或全局数据,也不调用不可重入函数。

  2. 线程安全函数要解决的问题是,多个线程调用函数时访问资源冲突。

① : 函数如果使用静态变量,通过加锁后可以转成线程安全函数,但仍然有可能不是可重入的,比如strtok

strtok是既不可重入的,也不是线程安全的。

加锁的strtok不是可重入的,但线程安全。

而strtok_r既是可重入的,也是线程安全的。

区别和联系

  1. 可重入是对函数相当严格的要求,绝大部分函数都不是可重入的(APUE上有一个reentrant函数的列表).

什么时候我们需要reentrant函数呢?
只有一个函数需要在同一个线程中需要进入两次以上,我们才需要
reentrant函数.这些情况主要是异步信号处理,递归函数等等.(non-reentrant的递归函数也不一定会
出错,出不出错取决于你怎么定义和使用该函数). 大部分时候,我们并不需要函数是reentrant的.

  1. 在多线程环境当中,只要求多个线程可以同时调用一个函数时,该函数只要是线程安全的就可以了.

  2. 可重入和线程安全的本质的区别就在于,可重入函数要求即使在同一个线程中任意地进入两次以上,也能正确执行.

大家常用的malloc函数是一个典型的non-reentrant但是是thread safe函数,这就说明,我们可以方便的
在多个线程中同时调用malloc,但是,如果将malloc函数放入信号处理函数中去,这是一件很危险的事情.

  1. 可重入函数一般(网上说法很多,但最起码我没见过反例)都是线程安全函数.
    不能简单的通过加锁,来使得non-reentrant函数变成 reentrant函数
  "使用的全局变量的函数也不一定是不可重入的。"
  这句是正确的,只要正确使用就可以了,但是不使用全局变量是写可重入函数的简单方法.
 
  "调用了不可重入函数的函数不一定是不可重入的。"
  这句是不对的,因为你无法保证被调用的不可重入函数部分不被重入

如图所示:

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值