0

I'm writing a simple program, and it gives me an error when I pass a non-integer value to the sleep() function. Is there another function, or a different way to use sleep(), that will allow me to pause the program temporarily for less than a second (or, say, 2.5)?

mario.c:34:13: error: implicit declaration of function 'usleep' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
usleep(30000);
^

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Allydra
  • 149
  • 1
  • 4

6 Answers6

4

usleep will pause for a particular number of microseconds. For example:

usleep(500000);

will pause for half a second.

On some systems, and depending on compiler configuration etc, you may need to define _GNU_SOURCE before including unistd.h (ideally, at the start of the source file), with:

#define _GNU_SOURCE
user253751
  • 57,427
  • 7
  • 48
  • 90
  • Although if you are on Windows, there is no `usleep().` There, you would use `Sleep(n)` with milliseconds as the parameter n. – JohnH Mar 24 '15 at 21:58
  • When I use usleep it gives me an error, I updated question with the given error. – Allydra Mar 24 '15 at 22:10
  • Both `usleep` and `nanosleep` are "newer" features which require turning on extensions over the original/antique interfaces. – Thomas Dickey Mar 25 '15 at 01:23
  • @NoahTronic what is your Linux distribution, gcc version and glibc version? (For the last one, run `/lib/libc.so.6`. For the second one, `gcc --version`) – user253751 Mar 25 '15 at 02:56
  • Actually, `_GNU_SOURCE` should be defined in the build-system rather than within a source-file, due to the way predefined symbols are handled. As I noted below, those functions have been available for quite a while. – Thomas Dickey Mar 25 '15 at 08:25
2

POSIX.1-2001 standard defines function nanosleep(), which is perfect for this. Unlike sleep() and usleep(), nanosleep() does not interfere with signals.

Current Linux C libraries tend to implement usleep() as a wrapper around nanosleep(), however. You can see this if you strace a test program (say, run strace /bin/sleep 1).

However, as nanosleep() is part of POSIX.1-2001 standard, it is definitely recommended.

For example:

#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;
}

Most of the logic above is to make sure (regardless of floating-point rounding mode et cetera) that the nanoseconds field is always within [0, 999999999], inclusive, and to make it safe to call it with negative values (in which case it'll just return zero).

If you want to specify the duration in integer milliseconds, you could use

#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;
}

It is not necessary to zero out rem, above, but written this way, these two functions are extremely robust, even against an occasional system hiccup or library bug.

Nominal Animal
  • 38,216
  • 5
  • 59
  • 86
0

The apparent problem with the original suggestion to use usleep was overlooking _GNU_SOURCE, a given for Linux with almost any POSIX-extension.

This compiles without warning for me, using c99 with the strict warning flags:

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

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

and (extracted from other scripts)

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 "$@"

The usleep and nanosleep functions are extensions, as noted. More commonly, select or poll are used. Those functions are used to wait for a specified interval of time for activity on one or more open files. As a special case, select does not even have to wait for a file, but simply use the time interval. Like nanosleep, select uses a structure for the time interval to allow double-precision values -- but its range of values starts with microseconds while nanosleep starts with nanoseconds.

These functions are all part of the Linux C library.

ncurses (like any X/Open curses) provides a function napms which waits for milliseconds. Internally, ncurses uses (since 1998) nanosleep or usleep depending on their availability (they are extensions after all), or an internal function that uses select or poll, also depending on availability.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
0

Use this macro to pause for non-integer seconds:

#include "unistd.h"
#define mysleep(s) usleep(s*1000000)
durian808
  • 1
  • 1
-1

sleep()'s int value is for a pause time in milliseconds, not seconds. So, to pause for one second, you'd pass it 1000. For 2.5 seconds, you'd pass it 2500. For a half second, you'd pass 500.

Chris V
  • 1
  • 2
-3

This will let you specify a delay as a float in seconds.
The function executes until the difference between start and stop is greater than the requested delay.

#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();
    }
}
user3121023
  • 8,181
  • 5
  • 18
  • 16