【问题标题】:Does a milter callback really need to be re-entrant?milter 回调真的需要重入吗?
【发布时间】:2017-11-01 11:05:38
【问题描述】:

我需要为 Sendmail 开发一个 milter,并且考虑了很长时间我应该使用哪种语言/框架。最后,我决定直接使用 milter API 用纯 C 语言来完成。

我研究了the milter API documentation 并认为我已经掌握了这些概念。但是有一件事情让我非常担心。来自this section

一个过滤器进程可以处理任意数量的连接 同时。因此,所有过滤回调必须是可重入的, 并使用一些适当的外部同步方法来访问 全球数据 [...]。

虽然我非常理解为什么回调必须是线程安全的,但我不明白为什么它们必须是可重入的。我无法想象可以从中断或信号处理程序中调用这些回调(也许除了中止回调,我将不得不重新阅读此内容)。

要求可重入的问题是可重入函数不能调用不可重入代码。因此,如果回调真的必须是可重入的,我就不能使用malloc() 和那里的大多数其他库函数;来自man 3 malloc

为避免多线程应用程序损坏,使用互斥锁 在内部保护使用的内存管理数据结构 通过这些功能 [...]

这肯定意味着malloc() 是线程安全的,这可能意味着malloc() 不可重入,因此没有使用它的函数。

所以我有两个问题:

1) milter 回调是否真的需要重入,或者这实际上是 milter API 文档中“需要线程安全”的一个非常奇怪的措辞?

2) 如果他们真的需要重入,我该如何规避上面提到的问题?由于 milter API 的特性,我很难想象如何在不使用malloc() 和其他不可重入库函数的情况下在回调中做一些合理的事情。

【问题讨论】:

  • “这肯定意味着 malloc() 是线程安全的,它可能意味着 malloc() 不是可重入的。”线程安全的东西也可能是可重入的,但不一定反之亦然。想象一个将函数指针传递给函数的单线程应用程序(例如,信号槽概念中的信号处理程序)。这可能会导致重新进入成为问题的情况,尽管线程安全不是一个问题。恕我直言,如果 malloc() 被授予线程安全的,我敢打赌它也是可重入的。
  • 找到一个很好的问答:SO: Threadsafe vs re-entrant
  • @Scheff 我相信malloc() 是线程安全的原因是它们使用互斥锁(即一种锁)。我认为malloc() 不可重入的原因是他们使用互斥锁(即一种锁)...
  • 好吧,我按照上面提供的链接重新阅读了一遍。 (当前)last answer 明确区分了线程安全和可重入。以前没见过这么清楚的。因此,我必须承认malloc() 可能是线程安全的,但不一定是可重入的(如果手册中没有说明)。

标签: c sendmail reentrancy milter


【解决方案1】:

在 Milter-API 的上下文中(还强调它在内部使用 posix 线程),“可重入”函数被定义为可以安全地从多个线程同时执行的函数。这意味着不会产生竞争条件。

“可重入”一词的这种用法与其他 UNIX/Linux API 文档(例如 strtok)一致:

strtok_r() 函数是strtok() 的可重入版本。 [..]

┌───────────┬───────────────┬───────────────────────┐
│Interface  │ Attribute     │ Value                 │
├───────────┼───────────────┼───────────────────────┤
│strtok()   │ Thread safety │ MT-Unsafe race:strtok │
├───────────┼───────────────┼───────────────────────┤
│strtok_r() │ Thread safety │ MT-Safe               │
└───────────┴───────────────┴───────────────────────┘

另请参阅其他 *_r() 函数,例如 ctime_r()gmtime_r() 等。

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 2012-03-13
    • 2020-01-29
    • 2014-02-28
    • 2011-01-28
    • 1970-01-01
    相关资源
    最近更新 更多