c-milter回调真的需要重新进入吗



我需要为Sendmail开发一个milter,并且已经考虑了很长时间应该使用哪种语言/框架。最后,我决定直接使用milter API在普通C中实现它。

我已经学习了milter API文档,并且认为我已经掌握了这些概念。但有一件事让我非常担心。来自本节:

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

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

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

为了避免多线程应用程序中的损坏,使用了互斥内部保护所采用的内存管理数据结构通过这些功能〔…〕

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

所以我有两个问题:

1) milter回调真的需要重新集中吗?或者这实际上是milter API文档中"需要线程安全"的一个非常奇怪的措辞吗?

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

在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()等。

最新更新