简体   繁体   English

有没有办法测试 C 标准库中是否提供线程安全函数?

[英]Is there a way to test whether thread safe functions are available in the C standard library?

In regards to the thread safe functions in newer versions of the C standard library, is there a cross-platform way to tell if these are available via pre-processor definition?关于较新版本的 C 标准库中的线程安全函数,是否有一种跨平台的方法可以通过预处理器定义来判断这些函数是否可用? I am referring to functions such as localtime_r() .我指的是localtime_r()等函数。

If there is not a standard way, what is the reliable way in GCC?如果没有标准方式,那么GCC中可靠的方式是什么? [EDIT] Or posix systems with unistd.h? [编辑] 还是带有 unistd.h 的 posix 系统?

There is no standard way to test that, which means there is no way to test it across all platforms.没有标准的方法来测试它,这意味着无法在所有平台上测试它。 Tools like autoconf will create a tiny C program that calls this function and then try to compile and link it. autoconf工具将创建一个调用此函数的微型 C 程序,然后尝试编译和链接它。 It this works, looks like the function exists, if not, then it may not exist (or the compiler options are wrong and the appropriate CFLAGS need to be set).这有效,看起来该函数存在,如果不存在,则它可能不存在(或编译器选项错误,需要设置适当的CFLAGS )。

So you have basically 6 options:所以你基本上有 6 个选择:

  1. Require them to exist.要求它们存在。 Your code can only work on platforms where they exist;你的代码只能在它们存在的平台上工作; period.时期。 If they don't exist, compilation will fail, but that is not your problem, since the platform violates your minimum requirements.如果它们不存在,编译将失败,但这不是您的问题,因为平台违反了您的最低要求。

  2. Avoid using them.避免使用它们。 If you use the non-thread safe ones, maybe protected by a global lock (eg a mutex), it doesn't matter if they exist or not.如果您使用非线程安全的,可能受全局锁(例如互斥锁)保护,它们是否存在并不重要。 Of course your code will then only work on platforms with POSIX mutexes, however, if a platform has no POSIX mutexes, it won't have POSIX threads either and if it has no POSIX threads (and I guess you are probably using POSIX threads w/o supporting any alternative), why would you have to worry about thread-safety in the first place?当然,您的代码只能在具有 POSIX 互斥锁的平台上运行,但是,如果一个平台没有 POSIX 互斥锁,那么它也不会有 POSIX 线程,如果它没有 POSIX 线程(我猜您可能正在使用 POSIX 线程 w /o 支持任何替代方案),为什么您首先要担心线程安全?

  3. Decide at runtime.在运行时决定。 Depending on the platform, either do a "weak link", so you can test at runtime if the function was found or not (a pointer to the function will point to NULL if it wasn't) or alternatively resolve the symbol dynamically using something like dlsym() (which is also not really portable, but widely supported in the Linux/UNIX world).根据平台,要么做一个“弱链接”,这样你就可以在运行时测试是否找到了函数(如果没有找到,指向函数的指针将指向NULL ),或者使用某些东西动态解析符号像dlsym() (它也不是真正可移植的,但在 Linux/UNIX 世界中得到广泛支持)。 However, in that case you need a fallback if the function is not found at runtime.但是,在这种情况下,如果在运行时找不到该函数,则需要回退。

  4. Use a tool like autoconf , some other tool with similar functionality, or your own configuration script to determine this prior to start of compilation (and maybe set preprocessor macros depending on result).使用类似autoconf工具、具有类似功能的其他工具或您自己的配置脚本在开始编译之前确定这一点(并且可能根据结果设置预处理器宏)。 In that case you will also need a fallback solution.在这种情况下,您还需要一个后备解决方案。

  5. Limit usage to well known platforms.将使用限制在众所周知的平台上。 Whether this function is available on a certain platform is usually known (and once it is available, it won't go away in the future).这个功能在某个平台上是否可用通常是已知的(一旦可用,将来就不会消失)。 Most platforms expose preprocessor macros to test what kind of platform that is and sometimes even which version.大多数平台公开预处理器宏来测试平台是什么类型,有时甚至是哪个版本。 Eg if you know that GNU/Linux, Android, Free/Open/NetBSD, Solaris, iOS and MacOS X all offer this function, test if you are compiling for one of these platforms and if yes, use it.例如,如果您知道 GNU/Linux、Android、Free/Open/NetBSD、Solaris、iOS 和 MacOS X 都提供此功能,请测试您是否正在为这些平台之一进行编译,如果是,请使用它。 If the code is compiled for another platform (or if you cannot determine what platform that is), it may or may not offer this function, but since you cannot say for sure, better be safe and use the fallback.如果代码是为另一个平台编译的(或者如果您无法确定它是什么平台),它可能会或可能不会提供此功能,但由于您无法确定,最好确保安全并使用回退。

  6. Let the user decide.让用户决定。 Either always use the fallback, unless the user has signaled support or do it the other way round (which makes probably more sense), always assume it is there and in case compilation fails, offer a way the user can force your code into "compatibility mode", by somehow specifying that thread-safe-functions are not available (eg by setting an environment variable or by using a different make target).要么始终使用回退,除非用户表示支持或反其道而行(这可能更有意义),始终假设它在那里,以防编译失败,提供一种用户可以强制您的代码“兼容”的方法模式”,通过某种方式指定线程安全函数不可用(例如,通过设置环境变量或使用不同的 make 目标)。 Of course this is the least convenient method for the (poor) user.当然,对于(穷)用户来说,这是最不方便的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM