how can I pause and then resume a call to `sleep` how can I pause and then resume a call to `sleep` bash bash

how can I pause and then resume a call to `sleep`


sleep(3) returns the number of seconds remaining if it was interrupted by a signal, but seconds are poor granularity, so it's better to use clock_nanosleep(2).

clock_nanosleep also has the advantage of allowing you to specify what kind of clock you want to sleep with - there are at least 7 different clocks, each useful in different circumstances. Chances are you want CLOCK_MONOTONIC though. (Note that you use no CPU time while sleeping, so you definitely don't want CLOCK_PROCESS_CPUTIME_ID (it would be meaningful in a multithreaded process))

Quoting the latter man page:

   If the call is interrupted by a signal handler, clock_nanosleep() fails   with the error EINTR.  In addition, if remain is not  NULL,  and  flags   was not TIMER_ABSTIME, it returns the remaining unslept time in remain.   This value can then be used to call clock_nanosleep()  again  and  com‐   plete a (relative) sleep.

Edit: I ended up writing a program demonstrating what you need to do, as well as the difference between the various clocks:

/*    Requires adding        -pthread -lrt    to your command line. */#define _POSIX_C_SOURCE 200112L#include <assert.h>#include <ctype.h>#include <errno.h>#include <limits.h>#include <pthread.h>#include <signal.h>#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>struct all_times{    struct timespec realtime;#ifdef CLOCK_REALTIME_COARSE    struct timespec realtime_coarse;#endif    struct timespec monotonic;#ifdef CLOCK_MONOTONIC_COARSE    struct timespec monotonic_coarse;#endif#ifdef CLOCK_MONOTONIC_RAW    struct timespec monotonic_raw;#endif#ifdef CLOCK_BOOTTIME    struct timespec boottime;#endif#ifdef CLOCK_PROCESS_CPUTIME_ID    struct timespec process_cputime_id;#endif#ifdef CLOCK_THREAD_CPUTIME_ID    struct timespec thread_cputime_id;#endif    struct timespec clock_getcpuclockid;    struct timespec pthread_getcpuclockid;};void get_all_times(struct all_times *times){    clockid_t clock;    struct timespec *spec;    memset(times, '\0', sizeof(*times));    clock = CLOCK_REALTIME;    spec = &times->realtime;    clock_gettime(clock, spec);#ifdef CLOCK_REALTIME_COARSE    clock = CLOCK_REALTIME_COARSE;    spec = &times->realtime_coarse;    clock_gettime(clock, spec);#endif    clock = CLOCK_MONOTONIC;    spec = &times->monotonic;    clock_gettime(clock, spec);#ifdef CLOCK_MONOTONIC_COARSE    clock = CLOCK_MONOTONIC_COARSE;    spec = &times->monotonic_coarse;    clock_gettime(clock, spec);#endif#ifdef CLOCK_MONOTONIC_RAW    clock = CLOCK_MONOTONIC_RAW;    spec = &times->monotonic_raw;    clock_gettime(clock, spec);#endif#ifdef CLOCK_BOOTTIME    clock = CLOCK_BOOTTIME;    spec = &times->boottime;    clock_gettime(clock, spec);#endif#ifdef CLOCK_PROCESS_CPUTIME_ID    clock = CLOCK_PROCESS_CPUTIME_ID;    spec = &times->process_cputime_id;    clock_gettime(clock, spec);#endif#ifdef CLOCK_THREAD_CPUTIME_ID    clock = CLOCK_THREAD_CPUTIME_ID;    spec = &times->thread_cputime_id;    clock_gettime(clock, spec);#endif    clock_getcpuclockid(0, &clock);    spec = &times->clock_getcpuclockid;    clock_gettime(clock, spec);    pthread_getcpuclockid(pthread_self(), &clock);    spec = &times->pthread_getcpuclockid;    clock_gettime(clock, spec);}void get_all_res(struct all_times *times){    clockid_t clock;    struct timespec *spec;    memset(times, '\0', sizeof(*times));    clock = CLOCK_REALTIME;    spec = &times->realtime;    clock_getres(clock, spec);#ifdef CLOCK_REALTIME_COARSE    clock = CLOCK_REALTIME_COARSE;    spec = &times->realtime_coarse;    clock_getres(clock, spec);#endif    clock = CLOCK_MONOTONIC;    spec = &times->monotonic;    clock_getres(clock, spec);#ifdef CLOCK_MONOTONIC_COARSE    clock = CLOCK_MONOTONIC_COARSE;    spec = &times->monotonic_coarse;    clock_getres(clock, spec);#endif#ifdef CLOCK_MONOTONIC_RAW    clock = CLOCK_MONOTONIC_RAW;    spec = &times->monotonic_raw;    clock_getres(clock, spec);#endif#ifdef CLOCK_BOOTTIME    clock = CLOCK_BOOTTIME;    spec = &times->boottime;    clock_getres(clock, spec);#endif#ifdef CLOCK_PROCESS_CPUTIME_ID    clock = CLOCK_PROCESS_CPUTIME_ID;    spec = &times->process_cputime_id;    clock_getres(clock, spec);#endif#ifdef CLOCK_THREAD_CPUTIME_ID    clock = CLOCK_THREAD_CPUTIME_ID;    spec = &times->thread_cputime_id;    clock_getres(clock, spec);#endif    clock_getcpuclockid(0, &clock);    spec = &times->clock_getcpuclockid;    clock_getres(clock, spec);    pthread_getcpuclockid(pthread_self(), &clock);    spec = &times->pthread_getcpuclockid;    clock_getres(clock, spec);}void diff_time(const struct timespec *start, const struct timespec *end, struct timespec *diff){    diff->tv_sec = end->tv_sec - start->tv_sec;    diff->tv_nsec = end->tv_nsec - start->tv_nsec;    if (diff->tv_nsec < 0)    {        diff->tv_nsec += 1000 * 1000 * 1000;        diff->tv_sec--;    }    assert (diff->tv_sec >= 0);    assert (diff->tv_nsec >= 0);}void diff_all_times(const struct all_times *start, const struct all_times *end, struct all_times *diff){    diff_time(&start->realtime, &end->realtime, &diff->realtime);    diff_time(&start->realtime, &end->realtime, &diff->realtime);#ifdef CLOCK_REALTIME_COARSE    diff_time(&start->realtime_coarse, &end->realtime_coarse, &diff->realtime_coarse);#endif    diff_time(&start->monotonic, &end->monotonic, &diff->monotonic);#ifdef CLOCK_MONOTONIC_COARSE    diff_time(&start->monotonic_coarse, &end->monotonic_coarse, &diff->monotonic_coarse);#endif#ifdef CLOCK_MONOTONIC_RAW    diff_time(&start->monotonic_raw, &end->monotonic_raw, &diff->monotonic_raw);#endif#ifdef CLOCK_BOOTTIME    diff_time(&start->boottime, &end->boottime, &diff->boottime);#endif#ifdef CLOCK_PROCESS_CPUTIME_ID    diff_time(&start->process_cputime_id, &end->process_cputime_id, &diff->process_cputime_id);#endif#ifdef CLOCK_THREAD_CPUTIME_ID    diff_time(&start->thread_cputime_id, &end->thread_cputime_id, &diff->thread_cputime_id);#endif    diff_time(&start->clock_getcpuclockid, &end->clock_getcpuclockid, &diff->clock_getcpuclockid);    diff_time(&start->pthread_getcpuclockid, &end->pthread_getcpuclockid, &diff->pthread_getcpuclockid);}void print_all_times(const struct all_times *start, const struct all_times *end, const struct all_times *diff, const struct all_times *res){    printf("%-27s %15s %-9s %15s %-9s %5s %-9s %5s %-9s\n", "clock", "", "start", "", "end", "", "diff", "", "res");    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_REALTIME", (long long)start->realtime.tv_sec, start->realtime.tv_nsec, (long long)end->realtime.tv_sec, end->realtime.tv_nsec, (long long)diff->realtime.tv_sec, diff->realtime.tv_nsec, (long long)res->realtime.tv_sec, res->realtime.tv_nsec);    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_REALTIME", (long long)start->realtime.tv_sec, start->realtime.tv_nsec, (long long)end->realtime.tv_sec, end->realtime.tv_nsec, (long long)diff->realtime.tv_sec, diff->realtime.tv_nsec, (long long)res->realtime.tv_sec, res->realtime.tv_nsec);#ifdef CLOCK_REALTIME_COARSE    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_REALTIME_COARSE", (long long)start->realtime_coarse.tv_sec, start->realtime_coarse.tv_nsec, (long long)end->realtime_coarse.tv_sec, end->realtime_coarse.tv_nsec, (long long)diff->realtime_coarse.tv_sec, diff->realtime_coarse.tv_nsec, (long long)res->realtime_coarse.tv_sec, res->realtime_coarse.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_REALTIME_COARSE");#endif    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_MONOTONIC", (long long)start->monotonic.tv_sec, start->monotonic.tv_nsec, (long long)end->monotonic.tv_sec, end->monotonic.tv_nsec, (long long)diff->monotonic.tv_sec, diff->monotonic.tv_nsec, (long long)res->monotonic.tv_sec, res->monotonic.tv_nsec);#ifdef CLOCK_MONOTONIC_COARSE    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_MONOTONIC_COARSE", (long long)start->monotonic_coarse.tv_sec, start->monotonic_coarse.tv_nsec, (long long)end->monotonic_coarse.tv_sec, end->monotonic_coarse.tv_nsec, (long long)diff->monotonic_coarse.tv_sec, diff->monotonic_coarse.tv_nsec, (long long)res->monotonic_coarse.tv_sec, res->monotonic_coarse.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_MONOTONIC_COARSE");#endif#ifdef CLOCK_MONOTONIC_RAW    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_MONOTONIC_RAW", (long long)start->monotonic_raw.tv_sec, start->monotonic_raw.tv_nsec, (long long)end->monotonic_raw.tv_sec, end->monotonic_raw.tv_nsec, (long long)diff->monotonic_raw.tv_sec, diff->monotonic_raw.tv_nsec, (long long)res->monotonic_raw.tv_sec, res->monotonic_raw.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_MONOTONIC_RAW");#endif#ifdef CLOCK_BOOTTIME    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_BOOTTIME", (long long)start->boottime.tv_sec, start->boottime.tv_nsec, (long long)end->boottime.tv_sec, end->boottime.tv_nsec, (long long)diff->boottime.tv_sec, diff->boottime.tv_nsec, (long long)res->boottime.tv_sec, res->boottime.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_BOOTTIME");#endif#ifdef CLOCK_PROCESS_CPUTIME_ID    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_PROCESS_CPUTIME_ID", (long long)start->process_cputime_id.tv_sec, start->process_cputime_id.tv_nsec, (long long)end->process_cputime_id.tv_sec, end->process_cputime_id.tv_nsec, (long long)diff->process_cputime_id.tv_sec, diff->process_cputime_id.tv_nsec, (long long)res->process_cputime_id.tv_sec, res->process_cputime_id.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_PROCESS_CPUTIME_ID");#endif#ifdef CLOCK_THREAD_CPUTIME_ID    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "CLOCK_THREAD_CPUTIME_ID", (long long)start->thread_cputime_id.tv_sec, start->thread_cputime_id.tv_nsec, (long long)end->thread_cputime_id.tv_sec, end->thread_cputime_id.tv_nsec, (long long)diff->thread_cputime_id.tv_sec, diff->thread_cputime_id.tv_nsec, (long long)res->thread_cputime_id.tv_sec, res->thread_cputime_id.tv_nsec);#else    printf("%-27s (not available)\n", "CLOCK_THREAD_CPUTIME_ID");#endif    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "clock_getcpuclockid", (long long)start->clock_getcpuclockid.tv_sec, start->clock_getcpuclockid.tv_nsec, (long long)end->clock_getcpuclockid.tv_sec, end->clock_getcpuclockid.tv_nsec, (long long)diff->clock_getcpuclockid.tv_sec, diff->clock_getcpuclockid.tv_nsec, (long long)res->clock_getcpuclockid.tv_sec, res->clock_getcpuclockid.tv_nsec);    printf("%-27s %15lld.%09ld %15lld.%09ld %5lld.%09ld %5lld.%09ld\n", "pthread_getcpuclockid", (long long)start->pthread_getcpuclockid.tv_sec, start->pthread_getcpuclockid.tv_nsec, (long long)end->pthread_getcpuclockid.tv_sec, end->pthread_getcpuclockid.tv_nsec, (long long)diff->pthread_getcpuclockid.tv_sec, diff->pthread_getcpuclockid.tv_nsec, (long long)res->pthread_getcpuclockid.tv_sec, res->pthread_getcpuclockid.tv_nsec);}void signal_handler(int sig){    (void)sig;    /*        We don't actually need to do anything, just the presence of the        signal handler is enough to make `clock_nanosleep` return.        However, because somebody requested that we stop, we *should*        listen to them and actually stop.    */    raise(SIGSTOP);}void do_sleep(struct timespec *total){    int not_errno;    struct sigaction act;    memset(&act, '\0', sizeof(act));    act.sa_handler = signal_handler;    /* TODO - it is impossible to catch SIGSTOP, is there another way? */    sigaction(SIGTSTP, &act, NULL);    sigaction(SIGTTIN, &act, NULL);    sigaction(SIGTTOU, &act, NULL);    /*        Note: synchronous methods of signal handling do *not* work here.        The `clock_nanosleep` will just resume silently in that case.        Using `sigtimedwait` does not directly give is a `remain` value.    */    do    {        /* Important note: clock_nanosleep does *not* use `errno`. */        not_errno = clock_nanosleep(CLOCK_MONOTONIC, 0, total, total);    }    while (not_errno == EINTR);}static void die(const char *msg){    printf("%s\n", msg);    exit(1);}static void parse_time(char *str, struct timespec *spec){    unsigned long long sec, nsec, multiplier;    char *end;    if (!isdigit(str[0]))    {        die("Non-numeric character at start of duration.");    }    errno = 0;    sec = strtoull(str, &end, 10);    spec->tv_sec = sec;    if (errno || (unsigned long long)spec->tv_sec != sec)    {        die("Out-of-range duration.");    }    if (*end == '\0')    {        spec->tv_nsec = 0;        return;    }    if (*end != '.')    {        die("Non-numeric character in duration.");    }    ++end;    multiplier = 100 * 1000 * 1000;    nsec = 0;    while (*end)    {        unsigned long long digit = *end - '0';        if (digit >= 10)        {            die("Non-numeric character in fractional duration.");        }        nsec += multiplier * digit;        multiplier /= 10;        ++end;        /* TODO instead of truncating extra precision, round up? */    }    spec->tv_nsec = nsec;}int main(int argc, char **argv){    struct timespec total;    struct all_times start, end, diff, res;    if (argc != 2 || argv[1][0] == '-')    {        die("Usage: ./nanosleep sss[.mmmuuunnn]");    }    parse_time(argv[1], &total);    get_all_res(&res);    get_all_times(&start);    do_sleep(&total);    get_all_times(&end);    diff_all_times(&start, &end, &diff);    print_all_times(&start, &end, &diff, &res);    return 0;}

Output:

$ ./nanosleep 1.2clock                                       start                     end             diff            res      CLOCK_REALTIME                   1461281943.302055558      1461281944.502279160     1.200223602     0.000000001CLOCK_REALTIME                   1461281943.302055558      1461281944.502279160     1.200223602     0.000000001CLOCK_REALTIME_COARSE            1461281943.299600851      1461281944.499668121     1.200067270     0.004000000CLOCK_MONOTONIC                      130817.112863848          130818.313087604     1.200223756     0.000000001CLOCK_MONOTONIC_COARSE               130817.110408795          130818.310476065     1.200067270     0.004000000CLOCK_MONOTONIC_RAW                  130809.723951252          130810.924108013     1.200156761     0.000000001CLOCK_BOOTTIME                       198571.683842245          198572.884067547     1.200225302     0.000000001CLOCK_PROCESS_CPUTIME_ID                  0.002856240               0.002900410     0.000044170     0.000000001CLOCK_THREAD_CPUTIME_ID                   0.002857132               0.002903159     0.000046027     0.000000001clock_getcpuclockid                       0.002857981               0.002905128     0.000047147     0.000000001pthread_getcpuclockid                     0.002858526               0.002908051     0.000049525     0.000000001


Sorry I don't know the right solution.But I have an idea, I hope to help you.

If the code is below

{    ...    sleep(10);    ...}

The code maybe will become three part.sample code as below:

{//change code    ...    sleep_thread();    mutex_lock(&sleep_mutex);    ...}{//sleep thread    mutex_lock(&sleep_mutex);    sleep(10);    mutex_unlock(&sleep_mutex);}{//handle signal    if(receive_signal == SIGUSR)        mutex_unlock(&sleep_mutex);}


Maybe you can try as below, if you enter "ctrl + c":

void signal_fun(int singal){    printf("This is signal fun\n");}int main(int argc, char* argv[]){    signal(SIGINT, signal_fun);    sleep(10);    printf("This is main fun\n");    exit(EXIT_SUCCESS);}