c - 如何在没有 sleep 的情况下防止 C 中的 linux 软锁定/无响应

标签 c loops freeze

在 C 程序中长时间运行的 while 循环中,如何防止软锁定/无响应的正确方法是什么?

(dmesg 报告软锁定)

伪代码是这样的:

while( worktodo ) {
  worktodo = doWork();
}

我的代码当然要复杂得多,还包括一个每秒执行一次以报告进度的 printf 语句,但问题是,此时程序不再响应 ctrl+c。

我尝试过的方法确实有效(但我想要一个替代方案):

  • 每次循环迭代都执行 printf(不知道为什么,但程序再次以这种方式响应(???)) - 由于不需要的 printf 调用(每个 doWork() 调用不需要很长时间)而浪费了大量性能长)
  • 使用 sleep/usleep/... - 对我来说也是浪费(处理)时间,因为整个程序已经全速运行了几个小时

我正在考虑的是某种 process_waiting_events() 函数或类似函数,正常信号似乎工作正常,因为我可以在不同的 shell 上使用 kill 来停止程序。

其他背景信息:我正在使用 GWAN我的代码在 main.c“维护脚本”中运行,据我所知,它似乎在主线程中运行。

非常感谢。

P.S.:是的,我确实检查了我发现的所有其他关于软锁定的线程,但它们似乎都在询问为什么发生软锁定,而我知道为什么并且想有办法阻止它们。

P.P.S.:优化程序(使其运行更短)并不是一个真正的解决方案,因为我正在处理一个 29GB 的 bz2 文件,该文件提取到大约 400GB 的 xml,在单个线程上以每秒大约 10-40MB 的速度,所以即使在最大速度下,我也会受到 I/O 的限制,但仍会运行几个小时。

最佳答案

虽然使用线程提出的答案可能是一个选项,但实际上它只会将问题转移到不同的线程。毕竟我的解决方案是使用

sleep(0)

还测试了 sched_yield/pthread_yield,两者都没有真正帮助。不幸的是,我一直无法找到一个很好的资源来记录 linux 中的 sleep(0),但对于 Windows,documentation指出使用 0 值可以让线程放弃它是当前 cpu 切片的剩余部分。

事实证明,sleep(0) 很可能依赖于 linux 中所谓的 timer slack - 有关此的文章可以在这里找到:http://lwn.net/Articles/463357/

另一种可能性是使用 nanosleep(&(struct timespec){0}, NULL) 这似乎不一定依赖于 timer slack - linux man pages for nanosleep声明如果请求的间隔低于时钟粒度,它将向上舍入到时钟粒度,根据手册页,这在 linux 上取决于 CLOCK_MONOTONIC。因此,0 纳秒的值是完全有效的并且应该始终有效,因为时钟粒度永远不会为 0。

希望这对其他人也有帮助;)

关于c - 如何在没有 sleep 的情况下防止 C 中的 linux 软锁定/无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18736548/

相关文章:

javascript - typescript 节拍器

python - 将列表元素与列表列表元素进行比较并有条件地创建新列表

javascript - 如何使用按钮激活 For 循环以显示每次按钮单击的每个单独结果?

arduino - 从/dev/ttyACM0 读取输出会导致 beagle 板卡住(嵌入式内容)

java - 我的 java 程序一直卡住

将控制台的全部内容更改为反转视频

c - 为什么只有第一个中断起作用?

c - pthread_join() 导致段默认错误

c - (r+1 + (r >> 8)) >> 8 是做什么的?

delphi - 串行端口 WriteFile() 卡住