在 C 语言中有没有一个可以替代毫秒的睡眠函数?

我有一些源代码是在 Windows 上编译的,我正在把它转换成运行在 Red Hat Linux 上。

源代码包含了 <windows.h>头文件,程序员使用 Sleep()函数等待了几毫秒。这在 Linux 上不起作用。

但是,我可以使用 sleep(seconds)函数,但是它使用的是以秒为单位的整数。我不想把毫秒转换成秒。在 Linux 上进行 gcc 编译时,是否可以使用其他睡眠函数?

412096 次浏览

Yes-old POSIX标准定义了 usleep(),因此可以在 Linux 上使用:

int usleep(useconds_t usec);

描述

函数挂起调用线程的执行 (至少)使用微秒。睡眠时间可以稍微延长 任何系统活动,或处理调用的时间,或 系统定时器粒度。

usleep()采用 微秒,因此您必须将输入乘以1000才能在毫秒内睡眠。


usleep()已被废弃,随后被移出 POSIX,对于新的代码,首选 nanosleep():

#include <time.h>


int nanosleep(const struct timespec *req, struct timespec *rem);

描述

nanosleep()挂起调用线程的执行,直到至少超过 *req中指定的时间,或者 中触发处理程序调用的信号的传递 调用线程或终止进程的。

结构时间规格用于指定具有纳秒精度的时间间隔。它的定义如下:

struct timespec {
time_t tv_sec;        /* seconds */
long   tv_nsec;       /* nanoseconds */
};

一个使用 nanosleep()实现的 msleep()函数示例,如果被信号中断,则继续睡眠:

#include <time.h>
#include <errno.h>


/* msleep(): Sleep for the requested number of milliseconds. */
int msleep(long msec)
{
struct timespec ts;
int res;


if (msec < 0)
{
errno = EINVAL;
return -1;
}


ts.tv_sec = msec / 1000;
ts.tv_nsec = (msec % 1000) * 1000000;


do {
res = nanosleep(&ts, &ts);
} while (res && errno == EINTR);


return res;
}

除了 睡觉,简陋的 选择与 NULL 文件描述符集将让您以微秒精度暂停,没有风险的 SIGALRM并发症。

Sigtimedwait 和 sigwait info 提供了类似的行为。

#include <unistd.h>


int usleep(useconds_t useconds); //pass in microseconds

除了在 POSIX 2008中没有定义的 usleep()(虽然它是在 POSIX 2004之前定义的,并且显然可以在 Linux 和其他有 POSIX 遵从历史的平台上使用) ,POSIX 2008标准定义了 nanosleep():

nanosleep高分辨率睡眠

#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);

nanosleep()函数将导致当前线程暂停执行,直到 rqtp参数指定的时间间隔过去或者信号传递给调用线程,其操作是调用信号捕获函数或终止进程。由于参数值被四舍五入为睡眠分辨率的整数倍,或者由于系统对其他活动的调度,暂停时间可能比请求的时间长。但是,除了被信号中断的情况下,暂停时间不应小于 rqtp指定的时间,由系统时钟 CLOCK _ REALTIME 测量。

使用 nanosleep()功能对任何信号的作用或阻塞都没有影响。

你可以使用这个跨平台的功能:

#ifdef WIN32
#include <windows.h>
#elif _POSIX_C_SOURCE >= 199309L
#include <time.h>   // for nanosleep
#else
#include <unistd.h> // for usleep
#endif


void sleep_ms(int milliseconds){ // cross-platform sleep function
#ifdef WIN32
Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
#else
if (milliseconds >= 1000)
sleep(milliseconds / 1000);
usleep((milliseconds % 1000) * 1000);
#endif
}