使用线程安全库

Using thread-safe libraries

我能想到两种使用线程安全库的方法:

一个是有一个受互斥锁保护的库的全局实例,它由主线程初始化并由工作线程使用,如下所示:

mutex g_lib_mutex;
lib_t g_lib;

thread:
    lock(&g_lib_mutex);
    /* use lib */
    unlock(&g_lib_mutex);


main:
    lib_init(&g_lib);
    start_threads(thread);

    lock(&g_lib_mutex);
    /* use lib */
    unlock(&g_lib_mutex);

    join_threads();
    lib_close(&g_lib);

另一个,是让每个线程都有一个库的本地实例,像这样:

thread:
    lib_t g_lib;
    lib_init(&g_lib);
    /* use lib */
    lib_close(&g_lib);


main:
    start_threads(thread);
    lib_t g_lib;
    lib_init(&g_lib);
    /* use lib */
    lib_close(&g_lib);

以下哪种方式更正确/更可取?

在这两种情况下,我都需要使用全局互斥来保护库调用吗?

当我想到这个问题时,我正在尝试在多线程应用程序中使用 libmysql 和 POSIX 消息队列。

一般情况下,一个库只初始化一次。请记住,所有线程都发生在同一个进程的内存 space 中,因此无论您对线程 X 中的任何全局变量做什么,都适用于所有线程。每个进程应该只进行一次库初始化。

现在,库调用是线程安全的还是必须由互斥锁保护是您的库的问题。现代图书馆应该有关于允许从多线程调用哪些函数的明确文档。如果缺少该信息,您可以

  • 假设最坏的情况,并使用单个全局互斥锁封装所有改变库处理或调用库的内容,或者
  • 阅读库的源代码以找出可能出问题的地方,相应地引入安全措施 (mutexes/conditions),并确保没有人使用不同版本的库(可能会出现问题的地方)不同),或
  • 改进文档,将该补丁发送给上游开发人员,要求他们验证您在线程(非)安全中记录的内容是有意的并且符合现实,(文档补丁是,对于我所知道的任何项目,永远欢迎)或
  • 将库本身修改为线程安全的(使自己成为英雄)。