使用线程安全库

时间:2016-02-26 11:51:41

标签: c multithreading thread-safety pthreads

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

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

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消息队列。

1 个答案:

答案 0 :(得分:2)

通常,只初始化一次库。请记住,所有线程都在同一个进程中发生。内存空间,所以无论你对线程X中的任何全局变量做什么都适用于所有线程。库初始化应该每个进程只发生一次。

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

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