clock_nanosleep() 不会立即返回(当它应该返回时)[WSL 2]

clock_nanosleep() does not return immediately (when it should) [WSL 2]

提问人:dev-null 提问时间:11/2/2023 更新时间:11/2/2023 访问量:21

问:

我正在使用带有 TIMER_ABSTIME 标志的 clock_nanosleep() 来维护循环计时。这是在 WSL2 中运行的。clock_nanosleep() 手册页指出:

如果 flags TIMER_ABSTIME,则 request 被解释为由时钟 clockid 测量的绝对时间。如果 request 小于或等于时钟的当前值,则 clock_nanosleep() 会立即返回,而不会挂起调用线程。

在我的情况下,请求的时间确实是 <= 当前时间,但 clock_nanosleep() 不会立即返回。线程似乎进入睡眠状态,并发生上下文切换。

下面是一个可重现的示例,输出:

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>

#define timespeccmp(tvp, uvp, cmp)                  \
    (((tvp)->tv_sec == (uvp)->tv_sec) ?             \
        ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :           \
        ((tvp)->tv_sec cmp (uvp)->tv_sec))
#define timespecadd(tvp, uvp, vvp)                      \
    do {                                \
        (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;      \
        (vvp)->tv_nsec = (tvp)->tv_nsec + (uvp)->tv_nsec;   \
        if ((vvp)->tv_nsec >= 1000000000) {         \
            (vvp)->tv_sec++;                \
            (vvp)->tv_nsec -= 1000000000;           \
        }                           \
    } while (0)

static struct timespec nextcnt_spec;
static struct timespec tick_spec = {0UL, 1000000000UL / 250};
struct timespec nothing = {.tv_sec = 0, .tv_nsec = 0};
struct timespec now_spec;

int main(int argc, int *argv[])
{
  clock_gettime(CLOCK_MONOTONIC, &nextcnt_spec);
  timespecadd(&nextcnt_spec, &tick_spec, &nextcnt_spec);

  while (1)
  {
      clock_gettime(CLOCK_MONOTONIC, &now_spec);
      if (timespeccmp(&now_spec, &nextcnt_spec, >=))
      {
          timespecadd(&nextcnt_spec, &tick_spec, &nextcnt_spec);
      }

      printf("now: %d.%d\n", now_spec.tv_sec, now_spec.tv_nsec);
      clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &nextcnt_spec, NULL);
  }
}
now: 82942.980959346
now: 82942.997138210
now: 82943.13317148
now: 82943.29403662
now: 82943.45508177
now: 82943.61593249
now: 82943.77658352
now: 82943.93719126
now: 82943.109841360
now: 82943.125951165

如果它有用,以下是我的内核配置的相关部分:

#
# Timers subsystem
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ_COMMON=y
# CONFIG_HZ_PERIODIC is not set
CONFIG_NO_HZ_IDLE=y
# CONFIG_NO_HZ_FULL is not set
# CONFIG_NO_HZ is not set
CONFIG_HIGH_RES_TIMERS=y
# end of Timers subsystem

CONFIG_HZ_1000=y
CONFIG_HZ=1000
linux posix windows-subsystem-for-linux 调度 glibc

评论


答: 暂无答案