我怎么可以暂停,然后恢复到`sleep`通话 [英] how can I pause and then resume a call to `sleep`
问题描述
调用睡眠(10)
指睡眠中指定的秒数。当我输入休眠10我想,以等待10秒钟,但是当我使用CTRL-Z(或发送 SIGTSTP
)休眠指令之后,它不会停止计时器(或柜台),即使该进程已停止。
Calling sleep(10)
means to sleep for the specified number of seconds. When I type "sleep 10" I suppose to wait 10 seconds but when I'm using CTRL-Z (or sending SIGTSTP
) right after sleep command, it won't stop the "timer" (or the counter) even though that the process has stopped.
我可以通过职位见
的状态睡眠
已更改为结束
,但如果我会等待10秒钟,然后把这个过程推到前台,将完成立即,即使它跑不到10秒。
I can see via jobs
that the status of sleep
has changed to STOPPED
but if I'll wait 10 seconds and then send this process to the foreground it will finish immediately, even though it run less then 10 seconds.
所以,我的问题是我怎么能停止运行睡眠定时器?
So, my question is how can I stop sleep timer from running??
更新 ::我现在明白了,睡眠是使用挂钟时间,所以我怎么能实现睡眠与用户的CPU时间
Update:: I Understand now that sleep is using wall-clock time, so how can I implement sleep with a user cpu time
推荐答案
睡眠(3)
返回剩余的,如果它是由一个信号中断的秒数,而是以秒为粒度差,所以最好使用的 clock_nanosleep(2)
。
clock_nanosleep
还允许你指定你想要睡觉什么样的时钟的优势 - 至少有7种不同的时钟,在不同情况下每个有用的。有可能到头来你想要 CLOCK_MONOTONIC
虽然。 (请注意,您使用的没有的CPU时间睡觉,所以你绝对不希望 CLOCK_PROCESS_CPUTIME_ID
(这将是一个多线程进程有意义))
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))
引用后者手册页:
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.
编辑:最后我写一个程序演示,你需要做什么,以及各时钟之间的区别:
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 = ×->realtime;
clock_gettime(clock, spec);
#ifdef CLOCK_REALTIME_COARSE
clock = CLOCK_REALTIME_COARSE;
spec = ×->realtime_coarse;
clock_gettime(clock, spec);
#endif
clock = CLOCK_MONOTONIC;
spec = ×->monotonic;
clock_gettime(clock, spec);
#ifdef CLOCK_MONOTONIC_COARSE
clock = CLOCK_MONOTONIC_COARSE;
spec = ×->monotonic_coarse;
clock_gettime(clock, spec);
#endif
#ifdef CLOCK_MONOTONIC_RAW
clock = CLOCK_MONOTONIC_RAW;
spec = ×->monotonic_raw;
clock_gettime(clock, spec);
#endif
#ifdef CLOCK_BOOTTIME
clock = CLOCK_BOOTTIME;
spec = ×->boottime;
clock_gettime(clock, spec);
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
clock = CLOCK_PROCESS_CPUTIME_ID;
spec = ×->process_cputime_id;
clock_gettime(clock, spec);
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
clock = CLOCK_THREAD_CPUTIME_ID;
spec = ×->thread_cputime_id;
clock_gettime(clock, spec);
#endif
clock_getcpuclockid(0, &clock);
spec = ×->clock_getcpuclockid;
clock_gettime(clock, spec);
pthread_getcpuclockid(pthread_self(), &clock);
spec = ×->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 = ×->realtime;
clock_getres(clock, spec);
#ifdef CLOCK_REALTIME_COARSE
clock = CLOCK_REALTIME_COARSE;
spec = ×->realtime_coarse;
clock_getres(clock, spec);
#endif
clock = CLOCK_MONOTONIC;
spec = ×->monotonic;
clock_getres(clock, spec);
#ifdef CLOCK_MONOTONIC_COARSE
clock = CLOCK_MONOTONIC_COARSE;
spec = ×->monotonic_coarse;
clock_getres(clock, spec);
#endif
#ifdef CLOCK_MONOTONIC_RAW
clock = CLOCK_MONOTONIC_RAW;
spec = ×->monotonic_raw;
clock_getres(clock, spec);
#endif
#ifdef CLOCK_BOOTTIME
clock = CLOCK_BOOTTIME;
spec = ×->boottime;
clock_getres(clock, spec);
#endif
#ifdef CLOCK_PROCESS_CPUTIME_ID
clock = CLOCK_PROCESS_CPUTIME_ID;
spec = ×->process_cputime_id;
clock_getres(clock, spec);
#endif
#ifdef CLOCK_THREAD_CPUTIME_ID
clock = CLOCK_THREAD_CPUTIME_ID;
spec = ×->thread_cputime_id;
clock_getres(clock, spec);
#endif
clock_getcpuclockid(0, &clock);
spec = ×->clock_getcpuclockid;
clock_getres(clock, spec);
pthread_getcpuclockid(pthread_self(), &clock);
spec = ×->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;
}
输出:
$ ./nanosleep 1.2
clock start end diff res
CLOCK_REALTIME 1461281943.302055558 1461281944.502279160 1.200223602 0.000000001
CLOCK_REALTIME 1461281943.302055558 1461281944.502279160 1.200223602 0.000000001
CLOCK_REALTIME_COARSE 1461281943.299600851 1461281944.499668121 1.200067270 0.004000000
CLOCK_MONOTONIC 130817.112863848 130818.313087604 1.200223756 0.000000001
CLOCK_MONOTONIC_COARSE 130817.110408795 130818.310476065 1.200067270 0.004000000
CLOCK_MONOTONIC_RAW 130809.723951252 130810.924108013 1.200156761 0.000000001
CLOCK_BOOTTIME 198571.683842245 198572.884067547 1.200225302 0.000000001
CLOCK_PROCESS_CPUTIME_ID 0.002856240 0.002900410 0.000044170 0.000000001
CLOCK_THREAD_CPUTIME_ID 0.002857132 0.002903159 0.000046027 0.000000001
clock_getcpuclockid 0.002857981 0.002905128 0.000047147 0.000000001
pthread_getcpuclockid 0.002858526 0.002908051 0.000049525 0.000000001
这篇关于我怎么可以暂停,然后恢复到`sleep`通话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!