c - 运行时加载的共享库中的 Libcurl 和 curl_global_init

标签 c thread-safety libcurl glib

我正在开发一个照相亭应用程序,它使用 3 个模块来提供打印、捕获和触发功能。这个想法是人们可以为其开发扩展此功能的模块。这些模块被实现为共享库,当用户单击“开始”时,它们在运行时加载。

我正在尝试实现一个“打印”到 facebook 图片库的打印机模块。我想为此使用 libcurl。我的问题是初始化函数:curl_global_init() libcurl API 文档声明此函数绝对不是线程安全的。来自 the docs :

This function is not thread safe. You must not call it when any other thread in the program (i.e. a thread sharing the same memory) is running. This doesn't just mean no other thread that is using libcurl. Because curl_global_init() calls functions of other libraries that are similarly thread unsafe, it could conflict with any other thread that uses these other libraries.



Elsewhere在文档中它说:

The global constant situation merits special consideration when the code you are writing to use libcurl is not the main program, but rather a modular piece of a program, e.g. another library. As a module, your code doesn't know about other parts of the program -- it doesn't know whether they use libcurl or not. And its code doesn't necessarily run at the start and end of the whole program.

A module like this must have global constant functions of its own, just like curl_global_init() and curl_global_cleanup(). The module thus has control at the beginning and end of the program and has a place to call the libcurl functions.



...这似乎解决了这个问题。但是,这似乎意味着我的模块的 init()finalize()函数将在程序的开始和结束时调用。由于模块设计为在运行时可交换,因此我无法做到这一点。即使可以,我的应用程序也使用 GLib,根据他们的 documentation ,假设没有线程在运行是绝对不安全的:

...Since version 2.32, the GLib threading system is automatically initialized at the start of your program, and all thread-creation functions and synchronization primitives are available right away.

Note that it is not safe to assume that your program has no threads even if you don't call g_thread_new() yourself. GLib and GIO can and will create threads for their own purposes...



我的问题是:有什么方法可以安全地调用curl_global_init()在我的应用程序中?我可以调用curl_global_init() 的电话吗?和 curl_global_cleanup()在我模块的 init()finalize()职能?我需要寻找另一个 HTTP 库吗?

最佳答案

首先,您不会真正找到没有这些限制的任何其他库,因为它们是由 libcurl 从具有这些限制的 3rd 方(主要是 SSL)库继承的。例如 OpenSSL。

这就是说,global_init 的线程安全情况非常不幸,我们(在 curl 项目中)非常不喜欢这种情况,但只要我们使用其他库,我们就无能为力。这也意味着您的确切情况取决于您的 libcurl 构建使用的依赖库。

在大多数情况下,按照您建议的方式从模块 init() 函数调用 curl_global_init() 会非常好。当然,我不能保证 100% 肯定这是安全的,因为这里有一些我无法谈论的未知数。

关于c - 运行时加载的共享库中的 Libcurl 和 curl_global_init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22851092/

相关文章:

c - 多进程使用curl,什么时候必须调用curl_global_init?

c - feof,似乎不起作用 - 文本文件

c - 使用 fgetc 和 fgets 从 .txt 文件中提取文本

.net - 有没有一种简单的方法来拥有线程局部实例变量?

c - 如何使用 libcurl 检查接收到的摘要信息

python - pycurl: RETURNTRANSFER 选项不存在

c++ - 在运行时加载 DLL

用于轮询工作线程任务完成状态的C文件描述符

ios - 我们如何快速使 'static' 变量线程安全?

java - HashMap.toString() 方法的线程安全