【问题标题】:malloc() is non-reentrant but thread-safe? [duplicate]malloc() 是不可重入但线程安全的? [复制]
【发布时间】:2012-01-15 12:31:09
【问题描述】:

可能重复:
Malloc thread-safe?

我在阅读《Linux 编程接口》时并没有感到困惑。

从书中说 malloc 是不可重入的,因为它操纵全局链表数据结构,但通过使用互斥锁使其成为线程安全的。

我对此有点困惑:既然使用互斥锁是线程安全的,因此可以同时被多个线程调用,为什么它不是可重入函数? (如果我们说可重入意味着它可以被多个调用者同时调用)

另一个问题是,既然 malloc 是线程安全的,我们可以把它放在信号处理程序中吗? 我认为答案是肯定的,但我不确定,因为根据这本书,它说只有可重入或异步信号安全函数可以放在信号处理程序中。

谁能给我解释一下?

【问题讨论】:

  • malloc 的实现中是否包含互斥锁?

标签: c linux multithreading malloc reentrancy


【解决方案1】:

如果我们说可重入意味着它可以被多个人调用 同时来电

错了。可重入意味着您可以在前一个化身结束之前中断它并再次调用它。想象一下 malloc 看起来像这样:

lock(mutex);

/* Stuff. */

unlock(mutex):

如果在中途被打断,解锁前而其他人调用malloc 会怎样?

  • 在第二个上下文完成之前,第一个上下文无法继续
  • 第二个上下文在互斥锁上阻塞,直到第一个解锁互斥锁后才能继续

这是一个僵局。

另一个问题是,既然 malloc 是线程安全的,我们能不能把它 在信号处理程序中?我认为答案是肯定的

又错了。请参见上面的示例。想象一下主程序正在执行malloc 并且在函数实际结束之前您的处理程序调用了malloc。

【讨论】:

  • 感谢 cnicutar,答案非常明确!!
  • @kai:请注意,旧版本的 POSIX(2008 年之前)错误地使用可重入这个词来表示线程安全,这一事实加剧了问题(混淆了这些概念)......跨度>
【解决方案2】:

重入和线程安全是两个不同的概念。可重入函数可以是非线程安全的,而线程安全函数可以是不可重入的。

不保证 C 中的库函数是可重入的,并且只能从信号处理程序调用可重入函数。

【讨论】:

  • A reentrant function can be non-thread-safe ... 可以吗?
  • @iuliux:是的。在某些机器上,静态变量比基于堆栈的局部变量更快。进入时将其静态变量复制到堆栈,使用静态变量,然后从堆栈中恢复变量的代码将是可重入的,但不是线程安全的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多