如何在C中暂停非整数时间?

时间:2015-03-24 21:50:57

标签: c linux

我正在编写一个简单的程序,当我将非整数值传递给sleep()函数时,它会给我一个错误。是否有其他功能,或使用sleep()的不同方式,这将允许我暂时暂停程序不到一秒钟(或者说,2.5)?

  

mario.c:34:13:错误:C99中函数'usleep'的隐式声明无效[-Werror,-Wimplicit-function-declaration]
               usleep(30000);
               ^

6 个答案:

答案 0 :(得分:3)

usleep会暂停一段特定的微秒。例如:

usleep(500000);

将暂停半秒钟。

在某些系统上,根据编译器配置等,您可能需要在包含_GNU_SOURCE(理想情况下,在源文件的开头)之前定义unistd.h,并使用:

#define _GNU_SOURCE

答案 1 :(得分:2)

POSIX.1-2001标准定义了函数nanosleep(),这是完美的。与sleep()usleep()不同,nanosleep()不会干扰信号。

然而,当前的Linux C库倾向于将usleep()实现为nanosleep()的包装器。如果您strace测试程序(例如,运行strace /bin/sleep 1),则可以看到这一点。

但是,由于nanosleep()是POSIX.1-2001标准的一部分,因此绝对值得推荐。

例如:

#define _POSIX_C_SOURCE 200112L
#include <time.h>
#include <errno.h>

/* Sleep; returns un-slept (leftover) time.
*/
double dsleep(const double seconds)
{
    const long  sec = (long)seconds;
    const long  nsec = (long)((seconds - (double)sec) * 1e9);
    struct timespec  req, rem;

    if (sec < 0L)
        return 0.0;
    if (sec == 0L && nsec <= 0L)
        return 0.0;

    req.tv_sec = sec;
    if (nsec <= 0L)
        req.tv_nsec = 0L;
    else
    if (nsec <= 999999999L)
        req.tv_nsec = nsec;
    else
        req.tv_nsec = 999999999L;

    rem.tv_sec = 0;
    rem.tv_nsec = 0;

    if (nanosleep(&req, &rem) == -1) {
        if (errno == EINTR)
            return (double)rem.tv_sec + (double)rem.tv_nsec / 1000000000.0;
        else
            return seconds;
    } else
        return 0.0;
}

上面的大部分逻辑都是为了确保(无论浮点舍入模式等等)纳秒场总是在[0,999999999]内,包括在内,并且可以安全地用负值调用它(在这种情况下,它只会返回零)。

如果要以整数毫秒为单位指定持续时间,可以使用

#define _POSIX_C_SOURCE 200112L
#include <time.h>
#include <errno.h>

/* Sleep; returns un-slept (leftover) time.
*/
long msleep(const long ms)
{
    struct timespec  req, rem;

    if (ms <= 0L)
        return 0L;

    req.tv_sec = ms / 1000L;
    req.tv_nsec = (ms % 1000L) * 1000000L;
    rem.tv_sec = 0;
    rem.tv_nsec = 0;

    if (nanosleep(&req, &rem) == -1) {
        if (errno == EINTR)
            return (long)rem.tv_sec * 1000L + rem.tv_nsec / 1000000L;
        else
            return ms;
    } else
        return 0L;
}

上面没有必要将rem归零,但是以这种方式编写,这两个函数非常强大,即使是偶尔的系统打嗝或库错误。

答案 2 :(得分:0)

使用usleep的原始建议的明显问题是忽略_GNU_SOURCE,这是Linux的几乎所有POSIX扩展名。

使用带有严格警告标志的c99对我进行编译时没有任何警告:

#include <unistd.h>
#include <time.h>

int main(void)
{             
    usleep(1);
    nanosleep(0,0);
    return 0;
}

和(从其他脚本中提取)

ACTUAL_GCC=c99 gcc-stricter -D_GNU_SOURCE -c foo.c

#!/bin/sh
OPTS="-O -Wall -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Wconversion 
-W 
    -Wbad-function-cast 
    -Wcast-align 
    -Wcast-qual 
    -Wmissing-declarations 
    -Wnested-externs 
    -Wpointer-arith 
    -Wwrite-strings 
    -ansi 
    -pedantic 
 "
${ACTUAL_GCC:-gcc} $OPTS "$@"

如上所述,usleepnanosleep功能是扩展程序。更常见的是,使用selectpoll。这些函数用于等待一个或多个打开文件上的活动的指定时间间隔。作为一种特殊情况,select甚至不必等待文件,而只是使用时间间隔。与nanosleep类似,select使用时间间隔的结构来允许双精度值 - 但其值范围以微秒开始,而nanosleep以纳秒开始。

这些函数都是Linux C库的一部分。

ncurses(与任何X / Open curses一样)提供等待毫秒的函数napms。在内部,ncurses使用(自1998nanosleepusleep,具体取决于它们的可用性(毕竟它们是扩展),或使用select或{{1 },也取决于可用性。

答案 3 :(得分:0)

使用此宏暂停非整数秒:

#include "unistd.h"
#define mysleep(s) usleep(s*1000000)

答案 4 :(得分:-1)

sleep()的int值表示暂停时间,以毫秒为单位,而不是秒。所以,要暂停一秒钟,你就把它传给1000.在2.5秒内,你将它传给它2500.半秒钟,你将超过500秒。

答案 5 :(得分:-3)

这将允许您将延迟指定为以秒为单位的浮点数 该函数执行,直到start和stop之间的差值大于请求的延迟。

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

void floatdelay ( float delay);

int main()
{
    float pause = 1.2;
    floatdelay ( pause);
    return 0;
}

void floatdelay ( float delay)
{
    clock_t start;
    clock_t stop;

    start = clock();
    stop = clock();
    while ( ( (float)( stop - start)/ CLOCKS_PER_SEC) < delay) {
        stop = clock();
    }
}