Mat*_*roh 5 c linux bash time sleep
呼唤 sleep(10)意味着睡眠指定的秒数。当我键入“ sleep 10”时,我想等待10秒,但是当我SIGTSTP在sleep命令之后立即使用CTRL-Z(或发送)时,即使该过程也不会停止“ timer”(或计数器)已经停止。
我可以看到jobs状态sleep更改为,STOPPED但是如果我等待10秒钟,然后将此过程发送到前台,它将,即使它运行的时间少于10秒钟,立即完成。
因此,我的问题是如何停止睡眠计时器的运行?
更新 ::我现在了解睡眠使用的是时钟时间,因此如何使用用户cpu时间实现睡眠
sleep(3)返回被信号中断时剩余的秒数,但秒的粒度很差,因此最好使用clock_nanosleep(2).
clock_nanosleep还有一个优点是允许您指定您想用哪种时钟睡觉 - 至少有 7 种不同的时钟,每种时钟在不同的情况下都有用。但很可能你想要CLOCK_MONOTONIC。(请注意,您在睡眠时不使用CPU 时间,因此您绝对不希望这样做CLOCK_PROCESS_CPUTIME_ID(这在多线程进程中是有意义的))
引用后一个手册页:
\n\n If the call is interrupted by a signal handler, clock_nanosleep() fails\n with the error EINTR. In addition, if remain is not NULL, and flags\n was not TIMER_ABSTIME, it returns the remaining unslept time in remain.\n This value can then be used to call clock_nanosleep() again and com\xe2\x80\x90\n plete a (relative) sleep.\nRun Code Online (Sandbox Code Playgroud)\n\n编辑:我最终编写了一个程序来演示您需要做什么,以及各种时钟之间的差异:
\n\n/*\n Requires adding\n -pthread -lrt\n to your command line.\n */\n#define _POSIX_C_SOURCE 200112L\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <limits.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\nstruct all_times\n{\n struct timespec realtime;\n\n#ifdef CLOCK_REALTIME_COARSE\n struct timespec realtime_coarse;\n#endif\n\n struct timespec monotonic;\n\n#ifdef CLOCK_MONOTONIC_COARSE\n struct timespec monotonic_coarse;\n#endif\n\n#ifdef CLOCK_MONOTONIC_RAW\n struct timespec monotonic_raw;\n#endif\n\n#ifdef CLOCK_BOOTTIME\n struct timespec boottime;\n#endif\n\n#ifdef CLOCK_PROCESS_CPUTIME_ID\n struct timespec process_cputime_id;\n#endif\n\n#ifdef CLOCK_THREAD_CPUTIME_ID\n struct timespec thread_cputime_id;\n#endif\n\n struct timespec clock_getcpuclockid;\n\n struct timespec pthread_getcpuclockid;\n};\n\nvoid get_all_times(struct all_times *times)\n{\n clockid_t clock;\n struct timespec *spec;\n\n memset(times, \'\\0\', sizeof(*times));\n\n clock = CLOCK_REALTIME;\n spec = ×->realtime;\n clock_gettime(clock, spec);\n\n#ifdef CLOCK_REALTIME_COARSE\n clock = CLOCK_REALTIME_COARSE;\n spec = ×->realtime_coarse;\n clock_gettime(clock, spec);\n#endif\n\n clock = CLOCK_MONOTONIC;\n spec = ×->monotonic;\n clock_gettime(clock, spec);\n\n#ifdef CLOCK_MONOTONIC_COARSE\n clock = CLOCK_MONOTONIC_COARSE;\n spec = ×->monotonic_coarse;\n clock_gettime(clock, spec);\n#endif\n\n#ifdef CLOCK_MONOTONIC_RAW\n clock = CLOCK_MONOTONIC_RAW;\n spec = ×->monotonic_raw;\n clock_gettime(clock, spec);\n#endif\n\n#ifdef CLOCK_BOOTTIME\n clock = CLOCK_BOOTTIME;\n spec = ×->boottime;\n clock_gettime(clock, spec);\n#endif\n\n#ifdef CLOCK_PROCESS_CPUTIME_ID\n clock = CLOCK_PROCESS_CPUTIME_ID;\n spec = ×->process_cputime_id;\n clock_gettime(clock, spec);\n#endif\n\n#ifdef CLOCK_THREAD_CPUTIME_ID\n clock = CLOCK_THREAD_CPUTIME_ID;\n spec = ×->thread_cputime_id;\n clock_gettime(clock, spec);\n#endif\n\n clock_getcpuclockid(0, &clock);\n spec = ×->clock_getcpuclockid;\n clock_gettime(clock, spec);\n\n pthread_getcpuclockid(pthread_self(), &clock);\n spec = ×->pthread_getcpuclockid;\n clock_gettime(clock, spec);\n}\n\nvoid get_all_res(struct all_times *times)\n{\n clockid_t clock;\n struct timespec *spec;\n\n memset(times, \'\\0\', sizeof(*times));\n\n clock = CLOCK_REALTIME;\n spec = ×->realtime;\n clock_getres(clock, spec);\n\n#ifdef CLOCK_REALTIME_COARSE\n clock = CLOCK_REALTIME_COARSE;\n spec = ×->realtime_coarse;\n clock_getres(clock, spec);\n#endif\n\n clock = CLOCK_MONOTONIC;\n spec = ×->monotonic;\n clock_getres(clock, spec);\n\n#ifdef CLOCK_MONOTONIC_COARSE\n clock = CLOCK_MONOTONIC_COARSE;\n spec = ×->monotonic_coarse;\n clock_getres(clock, spec);\n#endif\n\n#ifdef CLOCK_MONOTONIC_RAW\n clock = CLOCK_MONOTONIC_RAW;\n spec = ×->monotonic_raw;\n clock_getres(clock, spec);\n#endif\n\n#ifdef CLOCK_BOOTTIME\n clock = CLOCK_BOOTTIME;\n spec = ×->boottime;\n clock_getres(clock, spec);\n#endif\n\n#ifdef CLOCK_PROCESS_CPUTIME_ID\n clock = CLOCK_PROCESS_CPUTIME_ID;\n spec = ×->process_cputime_id;\n clock_getres(clock, spec);\n#endif\n\n#ifdef CLOCK_THREAD_CPUTIME_ID\n clock = CLOCK_THREAD_CPUTIME_ID;\n spec = ×->thread_cputime_id;\n clock_getres(clock, spec);\n#endif\n\n clock_getcpuclockid(0, &clock);\n spec = ×->clock_getcpuclockid;\n clock_getres(clock, spec);\n\n pthread_getcpuclockid(pthread_self(), &clock);\n spec = ×->pthread_getcpuclockid;\n clock_getres(clock, spec);\n}\n\nvoid diff_time(const struct timespec *start, const struct timespec *end, struct timespec *diff)\n{\n diff->tv_sec = end->tv_sec - start->tv_sec;\n diff->tv_nsec = end->tv_nsec - start->tv_nsec;\n if (diff->tv_nsec < 0)\n {\n diff->tv_nsec += 1000 * 1000 * 1000;\n diff->tv_sec--;\n }\n assert (diff->tv_sec >= 0);\n assert (diff->tv_nsec >= 0);\n}\n\nvoid diff_all_times(const struct all_times *start, const struct all_times *end, struct all_times *diff)\n{\n diff_time(&start->realtime, &end->realtime, &diff->realtime);\n diff_time(&start->realtime, &end->realtime, &diff->realtime);\n\n#ifdef CLOCK_REALTIME_COARSE\n diff_time(&start->realtime_coarse, &end->realtime_coarse, &diff->realtime_coarse);\n#endif\n\n diff_time(&start->monotonic, &end->monotonic, &diff->monotonic);\n\n#ifdef CLOCK_MONOTONIC_COARSE\n diff_time(&start->monotonic_coarse, &end->monotonic_coarse, &diff->monotonic_coarse);\n#endif\n\n#ifdef CLOCK_MONOTONIC_RAW\n diff_time(&start->monotonic_raw, &end->monotonic_raw, &diff->monotonic_raw);\n#endif\n\n#ifdef CLOCK_BOOTTIME\n diff_time(&start->boottime, &end->boottime, &diff->boottime);\n#endif\n\n#ifdef CLOCK_PROCESS_CPUTIME_ID\n diff_time(&start->process_cputime_id, &end->process_cputime_id, &diff->process_cputime_id);\n#endif\n\n#ifdef CLOCK_THREAD_CPUTIME_ID\n diff_time(&start->thread_cputime_id, &end->thread_cputime_id, &diff->thread_cputime_id);\n#endif\n\n diff_time(&start->clock_getcpuclockid, &end->clock_getcpuclockid, &diff->clock_getcpuclockid);\n\n diff_time(&start->pthread_getcpuclockid, &end->pthread_getcpuclockid, &diff->pthread_getcpuclockid);\n}\n\nvoid print_all_times(const struct all_times *start, const struct all_times *end, const struct all_times *diff, const struct all_times *res)\n{\n printf("%-27s %15s %-9s %15s %-9s %5s %-9s %5s %-9s\\n", "clock", "", "start", "", "end", "", "diff", "", "res");\n\n 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);\n\n 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);\n\n#ifdef CLOCK_REALTIME_COARSE\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_REALTIME_COARSE");\n#endif\n\n 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);\n\n#ifdef CLOCK_MONOTONIC_COARSE\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_MONOTONIC_COARSE");\n#endif\n\n#ifdef CLOCK_MONOTONIC_RAW\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_MONOTONIC_RAW");\n#endif\n\n#ifdef CLOCK_BOOTTIME\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_BOOTTIME");\n#endif\n\n#ifdef CLOCK_PROCESS_CPUTIME_ID\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_PROCESS_CPUTIME_ID");\n#endif\n\n#ifdef CLOCK_THREAD_CPUTIME_ID\n 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);\n#else\n printf("%-27s (not available)\\n", "CLOCK_THREAD_CPUTIME_ID");\n#endif\n\n 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);\n\n 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);\n}\n\nvoid signal_handler(int sig)\n{\n (void)sig;\n /*\n We don\'t actually need to do anything, just the presence of the\n signal handler is enough to make `clock_nanosleep` return.\n\n However, because somebody requested that we stop, we *should*\n listen to them and actually stop.\n */\n raise(SIGSTOP);\n}\n\nvoid do_sleep(struct timespec *total)\n{\n int not_errno;\n struct sigaction act;\n memset(&act, \'\\0\', sizeof(act));\n act.sa_handler = signal_handler;\n /* TODO - it is impossible to catch SIGSTOP, is there another way? */\n sigaction(SIGTSTP, &act, NULL);\n sigaction(SIGTTIN, &act, NULL);\n sigaction(SIGTTOU, &act, NULL);\n /*\n Note: synchronous methods of signal handling do *not* work here.\n The `clock_nanosleep` will just resume silently in that case.\n Using `sigtimedwait` does not directly give is a `remain` value.\n */\n do\n {\n /* Important note: clock_nanosleep does *not* use `errno`. */\n not_errno = clock_nanosleep(CLOCK_MONOTONIC, 0, total, total);\n }\n while (not_errno == EINTR);\n}\n\n\n\nstatic void die(const char *msg)\n{\n printf("%s\\n", msg);\n exit(1);\n}\n\nstatic void parse_time(char *str, struct timespec *spec)\n{\n unsigned long long sec, nsec, multiplier;\n char *end;\n if (!isdigit(str[0]))\n {\n die("Non-numeric character at start of duration.");\n }\n errno = 0;\n sec = strtoull(str, &end, 10);\n spec->tv_sec = sec;\n if (errno || (unsigned long long)spec->tv_sec != sec)\n {\n die("Out-of-range duration.");\n }\n if (*end == \'\\0\')\n {\n spec->tv_nsec = 0;\n return;\n }\n if (*end != \'.\')\n {\n die("Non-numeric character in duration.");\n }\n ++end;\n multiplier = 100 * 1000 * 1000;\n nsec = 0;\n while (*end)\n {\n unsigned long long digit = *end - \'0\';\n if (digit >= 10)\n {\n die("Non-numeric character in fractional duration.");\n }\n nsec += multiplier * digit;\n multiplier /= 10;\n ++end;\n /* TODO instead of truncating extra precision, round up? */\n }\n spec->tv_nsec = nsec;\n}\n\nint main(int argc, char **argv)\n{\n struct timespec total;\n struct all_times start, end, diff, res;\n\n if (argc != 2 || argv[1][0] == \'-\')\n {\n die("Usage: ./nanosleep sss[.mmmuuunnn]");\n }\n parse_time(argv[1], &total);\n\n get_all_res(&res);\n get_all_times(&start);\n do_sleep(&total);\n get_all_times(&end);\n\n diff_all_times(&start, &end, &diff);\n print_all_times(&start, &end, &diff, &res);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n输出:
\n\n$ ./nanosleep 1.2\nclock start end diff res \nCLOCK_REALTIME 1461281943.302055558 1461281944.502279160 1.200223602 0.000000001\nCLOCK_REALTIME 1461281943.302055558 1461281944.502279160 1.200223602 0.000000001\nCLOCK_REALTIME_COARSE 1461281943.299600851 1461281944.499668121 1.200067270 0.004000000\nCLOCK_MONOTONIC 130817.112863848 130818.313087604 1.200223756 0.000000001\nCLOCK_MONOTONIC_COARSE 130817.110408795 130818.310476065 1.200067270 0.004000000\nCLOCK_MONOTONIC_RAW 130809.723951252 130810.924108013 1.200156761 0.000000001\nCLOCK_BOOTTIME 198571.683842245 198572.884067547 1.200225302 0.000000001\nCLOCK_PROCESS_CPUTIME_ID 0.002856240 0.002900410 0.000044170 0.000000001\nCLOCK_THREAD_CPUTIME_ID 0.002857132 0.002903159 0.000046027 0.000000001\nclock_getcpuclockid 0.002857981 0.002905128 0.000047147 0.000000001\npthread_getcpuclockid 0.002858526 0.002908051 0.000049525 0.000000001\nRun Code Online (Sandbox Code Playgroud)\n