gpt4 book ai didi

c - 隔离线程不安全的初始化函数

转载 作者:行者123 更新时间:2023-11-30 16:47:31 25 4
gpt4 key购买 nike

假设我有一个 C 库,需要非线程安全的初始化和清理函数。具体来说,这些函数可能会调用其他库中的其他线程不安全函数。我不知道(在默认构建中)这些库将是哪些。

现在考虑将 Java 绑定(bind)写入该库的情况。 Java 在运行任何 Java 代码之前会生成多个线程。更糟糕的是,对于(例如)Eclipse 插件来说,当我的代码收到控制权时,可能有多个线程正在运行 Java 代码。其他一些线程可能正在使用上述不安全函数。

我当前的计划是静态链接 C 库(在我的例子中是 libcurl)和所有传递依赖项 - 在我的例子中是 TLS 库(可能是 mbedTLS)和(在 Windows 平台上)显像管。幸运的是,libcurl 会清理它分配的所有内容,因此不会出现与从一个堆分配并将其释放到另一堆相关的问题。因为所有内容都是静态链接的,并且不会尝试加载任何其他共享库,所以我可以从静态初始化程序初始化 libcurl。

这还能用吗?有更好的办法吗?

编辑:序列化库调用不起作用但我相信我的解决方案可能起作用的原因是全局状态不仅存储在 libcurl 本身中,而且还存储在 libcurl 所依赖的库中。当我的代码加载时,其中一些库(例如 OpenSSL)可能正在被其他代码使用。所以我需要锁定整个过程。

我相信隔离全局状态起作用的原因是libcurl(及其依赖的每个库)在初始化后是线程安全的。我需要确保 libcurl 的初始化不会产生竞争条件。后来我就好了。

最佳答案

[更新和修订]

您担心的似乎是您将直接和间接绑定(bind)到某些 native 库(例如 mbedTLS),该 native 库需要非线程安全的一次性初始化,而这超出了您的能力为了检测或控制,进程的不同线程可能会同时尝试初始化该库,或者可能(不安全地)尝试多次初始化它。这显然是最坏的情况。

另一方面,您假设您可以成功构建一个整体的、可动态加载的库,其中包含您想要的 native 库及其所有依赖项(在内核之外)的传递闭包,从而确保该库不与进程加载的任何其他库共享状态。您断言在非线程安全初始化之后,组合堆栈将是线程安全的,至少在您打算使用它时是这样。您想了解如何初始化该库。

Java promise 每个类将由一个线程初始化,并且随后其初始化状态将对所有线程可见。问题,这当然意味着,如果您的 native 库的初始化完全作为类初始化的一部分来执行 - 例如 通过静态初始化程序,如您所建议的那样 - 那么正确的初始化状态将对所有 Java 线程可见。据我了解,这充分解决了问题。

我仍然怀疑构建整体库是否有必要,但如果您确实必须处理您似乎预料到的最坏情况,那么也许确实如此。然而,由于您无法将库与内核上的冲突需求隔离开来,因此可以想象该策略不够。这将是图书馆依赖您假设的共享状态的少数几个可以想象的充分理由之一,而您的策略将阻碍该特定目的。我无法判断这种可能性有多大,但我怀疑这种可能性很大。

关于c - 隔离线程不安全的初始化函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43329453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com