我有一个使用nanosleep
的程序(混合C和Fortran,虽然看起来并不相关)。但是,如果我的timespec
的{{1}}值为0,则它根本就不会睡觉。 tv_sec
值可能是一整秒的微秒,但它不会睡眠。 (如果tv_nsec
为tv_sec
,则可以暂停一秒钟。)为什么会这样?
为了让事情更加混乱,具有适当值的1
(即usleep
usec)会按预期暂停一会儿。
我在RHEL 5.8和RHEL 6.4框中看到了这个问题。两者都在使用995000
。
这里是调用nanosleep的函数:
gcc
显然,我实际上并不需要纳秒精度!
我还测试了一个我检查过返回值的版本;它总是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
输出参数(如果被中断则剩余时间)从未设置过。
答案 0 :(得分:7)
你错过了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
成员的顺序。
答案 1 :(得分:0)
我是这样做的,它起作用了......
#include <stdio.h>
#include <time.h> /* Needed for struct timespec */
int nsleep(long miliseconds)
{
struct timespec req, rem;
if(miliseconds > 999)
{
req.tv_sec = (int)(miliseconds / 1000); /* Must be Non-Negative */
req.tv_nsec = (miliseconds - ((long)req.tv_sec * 1000)) * 1000000; /* Must be in range of 0 to 999999999 */
}
else
{
req.tv_sec = 0; /* Must be Non-Negative */
req.tv_nsec = miliseconds * 1000000; /* Must be in range of 0 to 999999999 */
}
return nanosleep(&req , &rem);
}
int main()
{
int ret = nsleep(2500);
printf("sleep result %d\n",ret);
return 0;
}
答案 2 :(得分:0)
这是方法
{
"rules": {
"no-unused-vars": ["error", { "vars": "local", "args": "after-used", "ignoreRestSiblings": true }]
}
}
下一页将更好地解释这个概念 Convert milliseconds to timespec - GNU Porting