gpt4 book ai didi

c - nanosleep 不适用于小于一秒的值

转载 作者:IT王子 更新时间:2023-10-29 01:06:01 29 4
gpt4 key购买 nike

我有一个使用 nanosleep 的程序(混合了 C 和 Fortran,虽然这似乎不相关)。但是,如果我的 timespectv_sec 值为 0,它就不会休眠。 tv_nsec 值可能比整秒差几微秒,但它不会休眠。 (如果tv_sec1,睡一秒没问题。)为什么会这样?

为了让事情变得更加困惑,usleep 具有适当的值(即 995000 usec)按预期休眠了大约一秒钟。

我在 RHEL 5.8 和 RHEL 6.4 机器上看到了这个问题。两者都使用 gcc

这是调用 nanosleep 的函数:

void msleep(int *milliseconds)
{
long usec;
struct timespec sleep;
usec = (*milliseconds) % 1000;
sleep.tv_sec = (*milliseconds) / 1000;
sleep.tv_nsec = 1000*usec;
nanosleep(&sleep, NULL);
}

显然,我实际上不需要纳秒精度!

我还测试了一个确实检查返回值的版本;它始终为 0(成功),因此 rem 输出参数(如果被中断,则为剩余时间)从未设置。

最佳答案

您漏掉了 1000。

试试这个:

#define _POSIX_C_SOURCE 199309L /* shall be >= 199309L */

#include <time.h>

void msleep(int *milliseconds)
{
int ms_remaining = (*milliseconds) % 1000;
long usec = ms_remaining * 1000;
struct timespec ts_sleep;

ts_sleep.tv_sec = (*milliseconds) / 1000;
ts_sleep.tv_nsec = 1000*usec;
nanosleep(&ts_sleep, NULL);
}

更紧凑:

#define _POSIX_C_SOURCE 199309L /* shall be >= 199309L */

#include <time.h>

void msleep(int * pmilliseconds)
{
struct timespec ts_sleep =
{
*pmilliseconds / 1000,
(*pmilliseconds % 1000) * 1000000L
};

nanosleep(&ts_sleep, NULL);
}

最后是一个完整的实现,包括错误处理和nanosleep()被提前中断的情况:

#define _POSIX_C_SOURCE 199309L

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

int ms_sleep(unsigned int ms)
{
int result = 0;

{
struct timespec ts_remaining =
{
ms / 1000,
(ms % 1000) * 1000000L
};

do
{
struct timespec ts_sleep = ts_remaining;
result = nanosleep(&ts_sleep, &ts_remaining);
}
while ((EINTR == errno) && (-1 == result));
}

if (-1 == result)
{
perror("nanosleep() failed");
}

return result;
}

遵循包装器以满足 OP 的要求:

#include <errno.h>
#include <stdio.h>

int ms_sleep(unsigned int);

void msleep(int * pms)
{
int result = 0;

if ((NULL == pms) || (0 > *pms)) /* Check for valid input. */
{
errno = EINVAL;
result = -1;
}
else
{
result = ms_sleep(*pms));
}

if (-1 == result)
{
perror("ms_sleep() failed");
/* Exit and/or log error here. */
}
}

更新(引用 chux 下面的评论):

假设至少是C99,以上这部分代码

  struct timespec ts_sleep = 
{
*pmilliseconds / 1000,
(*pmilliseconds % 1000) * 1000000L
};

最好这样写

  struct timespec ts_sleep = 
{
.tv_sec = *pmilliseconds / 1000,
.tv_nsec = (*pmilliseconds % 1000) * 1000000L
};

不依赖于 struct timespec 成员的顺序。

关于c - nanosleep 不适用于小于一秒的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26063754/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com