【问题标题】:Portable thread-safety in C?C中的可移植线程安全?
【发布时间】:2009-08-02 19:28:12
【问题描述】:

目的

我正在编写一个小型库,其中最关心的是可移植性。它被设计为仅假设大多数符合 C90 (ISO/IEC 9899:1990) 的环境......仅此而已。该库提供的一组函数都对内部数据结构进行操作(读/写)。我考虑过其他一些设计替代方案,但对于库trying to achieve,似乎没有其他可行的方法。

问题

是否有任何可移植的算法、技术或咒语可用于确保线程安全?我不关心使功能可重入。此外,如果算法/技术/咒语是可移植的,我不关心速度或(可能)浪费资源。理想情况下,我不想依赖任何库(例如 GNU Pth)或特定于系统的操作(例如原子测试和设置)。

我考虑过修改Lamport's bakery algorithm,但我不知道如何将其更改为在线程调用的函数内部而不是在线程本身中工作。

非常感谢任何帮助。

【问题讨论】:

    标签: c algorithm multithreading thread-safety portability


    【解决方案1】:

    如果没有操作系统/硬件支持,至少是原子 CAS,那么您将无法做任何实际操作。不过,可移植库将各种平台抽象为一个通用接口。

    http://www.gnu.org/software/pth/related.html

    【讨论】:

      【解决方案2】:

      如今几乎所有系统(甚至 Windows)都可以运行 libpthread。

      【讨论】:

      • 从哪里可以获得有关 libpthread 的更多信息?一个简单的谷歌搜索似乎发现了一堆垃圾。
      • 您可以在 Windows 上通过 pthreads-win32 使用 pthreads;见sourceware.org/pthreads-win32
      • pthreads 几乎可用于任何 *nix,Windows 实现位于 sourceware.org/pthreads-win32 权威 dpcumentation 在这里:opengroup.org/onlinepubs/007908799/xsh/pthread.h.html 如果你走那条路,很容易暴露pthreads 给你的库的用户,这可能并不总是可取的
      • 我现在正在考虑抽象锁定和解锁过程,并使用一些预处理器宏来支持各种不同的线程库。
      • 这可能是最好的方法。我只是提供 mutex_init(void**);互斥锁(无效*);和 mutex_unlock(void *);我的项目使用。填充 mutex_posix.c 和 mutex_win32.c 中的实现,它们自然是有条件编译的,只要有可用的本机实现(如果平台支持线程,几乎总是存在),为像互斥锁这样简单的东西提供不同的实现很容易/跨度>
      【解决方案3】:

      Lamport 的面包店算法可能会起作用;不幸的是,它仍然存在实际问题。具体来说,许多 CPU 实现了out-of-order memory operations:即使您已将代码编译成完全正确的指令序列,CPU 在执行代码时可能会决定动态重新排序指令以获得更好的性能。解决这个问题的唯一方法是使用 memory barriers,它是高度系统和 CPU 特定的。

      您实际上只有两个选择:(1) 保持您的库线程不安全并让您的用户在文档中意识到这一点,或者 (2) 使用特定于平台的互斥锁。选项 2 可以通过使用另一个库来简化,该库为各种平台实现互斥锁并为您提供统一的抽象接口。

      【讨论】:

      • Lamport 算法是否也需要一致的内存缓存?我还没有看到证明,但在我看来,当前线程似乎依赖于在线程 j 写入 true 和线程 j 写入 false 之间的时间段内将每个 Entering[j] 视为 true。因此,即使可以处理写入顺序,此代码也可能无法在例如多核 ARM 机器上运行。同样,需要内存屏障或原子 CAS。
      【解决方案4】:

      函数要么不能是线程安全的,要么天生就是线程安全的,这取决于你如何看待它。线程/锁定天生就是特定于平台的。实际上,由您的库的 用户 来处理线程问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-22
        • 1970-01-01
        • 2014-04-24
        • 1970-01-01
        相关资源
        最近更新 更多