Tl;博士
如果您需要获取usleep()
用于编译的遗留代码,请将这些行添加到您在任何其他库之前包含的头文件中:
#define _XOPEN_SOURCE 600
#define _POSIX_C_SOURCE 200112L
或者将编译器标志添加-std=c11 -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112L
到您的 makefile 中。
这告诉环境您的程序使用的是旧版本的 UNIX API,在该版本usleep()
中未被弃用。
或者——如果这是新代码,肯定是——替换usleep()
为nanosleep()
,为您的库版本适当地设置功能测试宏,并检查您的代码库是否有其他错误。
在 Linux 上,您_XOPEN_SOURCE
可以_POSIX_C_SOURCE
检查man feature_test_macros
.
完整的图片
更长的答案:这就是发生的事情。
从历史上看,有几种不同的 UNIX 标准,最终每个人都想到的最佳实践是让代码指定它是为哪个版本的 UNIX API 编写的。程序员通过定义一个功能测试宏来做到这一点。
UNIX 中最早的分裂之一是 AT&T 的 System V 和加州大学的伯克利标准分发 (BSD)。由于 System V 是正式版本并且它的行为成为默认,而 BSD Unix 是一些最早的免费软件并在许多大学中使用,因此看到遗留代码声明_BSD_SOURCE
比_SVID_SOURCE
. 该_BSD_SOURCE
宏特别试图在 40 多年的时间里启用来自各种不同操作系统的扩展。有时,它甚至被用作非标准扩展的包罗万象。这两个宏都已弃用,并且与当前接受的答案相反,您永远不应该在新代码中使用任何一个。
在本世纪,有两个 UNIX 标准,POSIX 成为 IEEE 标准,以及来自开放组 (X/Open) 的单一 Unix 规范 (SUS)。X/Open SUS 是 POSIX 的超集,也是您通常编写的内容。曾经有许多不同的功能测试宏,您可以声明它们以启用这些标准的当前版本,并且仍然支持这些宏以实现向后兼容性。您可以在粘贴的条件中看到其中一些,但您在编写新代码时无需担心它们。代码检查的一个宏_XOPEN_SOURCE_EXTENDED
现在已过时,但历史上选择了 1995 年的 SUS 版本。
理论上,在任何现代版本的 UNIX 或 Linux 上设置的正确功能测试宏是_XOPEN_SOURCE
. 您应该查找您的库支持的最新版本号。在实践中,我认为还定义 是一种谨慎的防御性编码_POSIX_C_SOURCE
,以保证没有其他人可以不一致地设置它并破坏您的代码。您的问题是一个很好的例子:如果您设置_XOPEN_SOURCE
为向后兼容,但_POSIX_C_SOURCE
在工具链的其他地方设置为更新的版本,则更高版本的_POSIX_C_SOURCE
将优先且usleep()
不起作用。
所以,这些条件的意思是它usleep()
不是一个 POSIX 函数,但曾经出现在一些类似 BSD 的操作系统上,因此它在 1995 年进入了 SUS。它在 2008 年被弃用,并选择任何版本的 POSIX 或SUS 从那时起主动禁用它。因此,如果您选择 SUS 的 500 或 600 版本(并且另一个过时的同义词也将其打开),则启用它,但如果您选择任何最新版本的 POSIX 或 SUS,则不推荐使用。如果您选择“随心所欲”选项,它们也会启用,但这是个坏主意。