繁体   English   中英

clock_nanosleep():它忽略 timespec 结构

[英]clock_nanosleep(): It ignores timespec structure

我正在尝试创建这个基本clock_nanosleep示例,但它不会暂停我for循环,它会继续打印数字。 如果我取消注释//t.tv_nsec = s/1000000000; 不会打印任何内容,但会运行for循环。

// POSIX.1-2017 is what compiler is confined to.
#define _XOPEN_SOURCE 700

// C headers.
#include <stdint.h>
#include <time.h>
#include <stdio.h>
   
int main(int argc, char *argv[])
{
    // Counter.
    uint8_t i;

    // Time.
    int s = 1;

    // Create a timespec structure and calculate it's members.
    struct timespec t;
    t.tv_sec = s;
    //t.tv_nsec = s/1000000000;

    // Set flags i.e. TIMER_ABSTIME to 0 to use relative instead of absolute time.
    int flags = 0;

    // Choose the clock i.e. CLOCK_MONOTONIC is a "clock_id" for the clock started at system start.
    int clock_id = CLOCK_MONOTONIC;

    for(i = 0; i < 256; i++){
        printf("%d", i);

        // Because last argument is NULL in case of error, remaining time is not stored in "t".
        clock_nanosleep(clock_id, flags, &t, NULL);
    }

    return 0;

}

我完全不知道为什么这不起作用。 POSIX 声明:

int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp);

如果标志TIMER_ABSTIME没有在 flags 参数中设置, clock_nanosleep() function 将导致当前线程暂停执行,直到rqtp参数指定的时间间隔已经过去,或者信号被传递到调用线程并且它的动作是调用一个捕获信号的 function,或者进程终止。

我确保标志被清零。 我设置了rqtp&t

用于测量时间的时钟应为clock_id指定的时钟。

我确实使用了CLOCK_MONOTONIC

如果clock_nanosleep() function被信号中断返回,则返回对应的错误值。 对于相对的clock_nanosleep() function,如果rmtp参数不是NULL ,它引用的timespec结构应该被更新为包含间隔中剩余的时间量(请求的时间减去实际睡眠的时间)。 rqtprmtp arguments 可以指向同一个 object。 如果rmtp参数为NULL ,则不返回剩余时间。 绝对clock_nanosleep() function 对rmtp引用的结构没有影响。

我还将最后一个参数设置为NULL以便在clock_naanosleep()被任何信号中断时不存储剩余时间。

那么为什么这不起作用呢?

在这种情况下,您应该始终检查实际返回值是什么,在这种情况下将是EINVAL ,因为t.tv.nsec未初始化。

利用:

struct timespec t = {
    .tv_sec = s,
};

正确初始化所有字段,即使是您不打算使用的字段。

局部变量没有被隐式初始化。 因此,如果您不设置t.tv_nsec它可以包含任何值。 如果该值恰好超出 0 - 999999999 的范围,则clock_nanosleep将立即返回并返回错误代码。

设置t.tv_nsec时看不到任何 output 的原因是因为您的打印方式:

 printf("%d", i);

您没有在 output 中包含换行符。 stdout stream 是行缓冲的,因此它不会自动将 output stream 刷新到控制台。 \n添加到格式字符串的末尾,您将看到打印的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM