微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何创build一个仅在pthread链接时才使用互斥体的库?

我正在Linux上创build一个C库,它有几个function,它们共同操作一些全局数据。 为了使这些函数成为线程安全的,他们必须在代码中的适当位置使用互斥锁。

在Linux中,为了在应用程序中使用pthread,需要在适当的库中链接-lpthread 。 在编译我的库的情况下,如果它的用户决定在他们的应用程序中使用pthreads,并且他们不这样做,我想让它工作。

在开发人员在应用程序中不使用线程的情况下,它们不会与pthreads链接。 因此,我希望我编译的库不要求它,而且,在单线程应用程序中使用互斥体使用不必要的开销(更不用说是愚蠢的)。

是否有某种方式来编写代码(如果有必要,使用GCC扩展)只有某些符号被链接时,某个代码块才会运行? 我知道我可以使用dlopen()和朋友,但是这本身就需要一些我想要避免的东西。 我想我所要找的东西必须存在,因为几个标准函数在同一条船上,并且需要互斥体是线程安全的(而且是互斥的),但是即使不与pthread链接,也能工作。

Linux如何知道进程使用了​​多less物理内存?

在Linux下检测caching失误和命中

如何强制正在运行的程序使用外部方法将其I / O缓冲区的内容刷新到磁盘?

Eclipse,Ubuntu中未解决的<iostream>

远程桌面连接启动时检测?

在这一点上,我注意到66&67行上的FreeBSD的popen()函数使用了非可移植的检查 – isthreaded ,以确定是否使用线程,以及是否使用互斥锁。 我怀疑这样的东西是否以任何方式标准化。 但是更重要的是,如果符号不被识别,那么这样的代码就不能编译和链接,而在Linux中,如果pthread没有链接,互斥符号将不会存在。

总结一下:在Linux上,如何创build一个库,它知道什么时候使用线程,如果是,在适当的情况下使用互斥锁,并且不需要链接到pthread,除非应用程序开发人员特别想在某处使用线程。

拦截鼠标单击

素数查找器找不到素数,7点后停止

有没有办法恢复/恢复nohup查看控制台中的输出

在窗口上绘制位图时不希望的消除锯齿

哪个Linux发行版使用Linux内核是没有修改

经过一番测试,似乎Linux已经做了我想要的自动! 如果你使用线程,你只需要链接到pthreads,而不是如果你只是想要pthread互斥体的支持

在这个测试案例中:

#include <stdio.h> #include <errno.h> #include <pthread.h> int main() { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; if (!(errno = pthread_mutex_lock(&mutex))) { puts("Mutex locked!"); } else { perror("Could not lock mutex"); } if (!(errno = pthread_mutex_lock(&mutex))) { puts("Mutex locked!"); } else { perror("Could not lock mutex"); } return 0; }

当编译这没有pthreads链接,我看到“互斥锁! 两次。 这表明pthread_mutex_lock()本质上是一个非操作符。 但是与pthreads链接,运行此应用程序将停止后第一次“互斥锁! 被打印。

因此,我可以在适当的情况下在我的库中使用互斥锁,并且不需要使用pthread来使用,也不需要(不必要的)开销。

通常的解决方案是:

使用#define开关在构建时控制是否调用pthreads函数,并让你的构建过程创建你的库的两个版本:一个是pthread-aware,一个是不知名的。 依靠你的图书馆的用户链接正确的。

不要直接调用pthreads函数,而是调用用户提供的lock和unlock回调(如果需要,也可以调用线程本地存储)。 库用户负责分配和调用适当的锁定机制,这也允许他们使用非线程库线程库。

什么都不要做,只是记录用户代码应该确保你的库函数不是从多个线程同时输入的。

glibc再次做了一些不同的事情 – 它使用带有惰性绑定符号的技巧,只有在链接到二进制文件中时才调用pthreads函数。 这不是可移植的,因为它依赖于pibread的glibc实现的具体细节。 查看__libc_maybe_call()的定义 :

#ifdef __PIC__ # define __libc_maybe_call(FUNC,ARGS,ELSE) (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); _fn != NULL ? (*_fn) ARGS : ELSE; })) #else # define __libc_maybe_call(FUNC,ELSE) (FUNC != NULL ? FUNC ARGS : ELSE) #endif

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐