我用 C 语言编写了一段代码sleep(0.01);
。由于某种原因,机器死机了,根据回溯,它似乎挂在了nanosleep()
或上__kernel_vsyscall ()
。
(gdb) bt
#0 0xffffe430 in __kernel_vsyscall ()
#1 0xf6f6bbe6 in nanosleep () from /lib/libc.so.6
#2 0xf6f6b9d9 in sleep () from /lib/libc.so.6
它不会每次都发生,所以这可能是我无法理解的竞争条件。
致力于 Linux 内核 3.10。
知道可能是什么原因造成的吗?
谢谢。
答案1
知道可能是什么原因造成的吗?
您的参数与0.01
预期/要求的参数类型不匹配。
根据手册页睡觉(),函数原型为:
unsigned int sleep(unsigned int seconds);
您传递的不是无符号整数值,而是浮点值,该值被解释为非常大的整数值。
睡眠定时器似乎永远不会过期,只是因为您没有等待足够长的时间。
有一些编译器选项可以/应该启用以产生错误或者至少对可疑代码发出警告(例如 -Wall)。
这种情况并不是每次都会发生,...
可能是因为睡觉()调用可以被信号处理程序中断。测试返回代码可以证实这一点。
答案2
谢谢大家的建议。
最终,我注意到nanosleep() 的手册页(由 使用sleep()
),通知在以非常高的速率接收信号的程序中使用它时可能出现的问题,这可能是我的情况:
如果捕获信号并使用 nanosleep() 的程序以非常高的速率接收信号,则内核计算休眠间隔和返回的剩余值时出现的调度延迟和舍入误差意味着剩余值可能会在 nanosleep() 调用的连续重新启动时稳步增加。为避免此类问题,请使用带有 TIMER_ABSTIME 标志的 clock_nanosleep(2) 来休眠到绝对截止时间。
我想我会尝试一下这个,因为对我来说,睡到绝对时间的方法而不是睡到相对时间的方法似乎更好。