在C程序中,如何正确地防止长时间运行的while循环中出现软锁定/无响应?
(dmesg正在报告软锁定)
伪代码如下:
while( worktodo ) {
worktodo = doWork();
}
当然,我的代码要复杂得多,而且还包含一个printf语句,该语句每秒执行一次以报告进度,但问题是,程序此时不再响应ctrl+c。
我试过的那些有用的东西(但我想要一个替代品):
执行printf的每一个循环迭代(不知道为什么,但是程序会以这种方式再次响应(?)???)) -由于不需要printf调用,浪费了很多性能(每个doWork()调用不会花费很长时间)
使用sleep/usleep/。。。-对我来说,这也是浪费时间,因为整个程序已经全速运行了几个小时了
我想的是某种进程等待事件(process_waiting_events()函数)之类的函数,正常的信号似乎工作正常,因为我可以在不同的shell上使用kill来停止程序。
其他背景信息:我正在使用GWAN并且我的代码在main.c“维护脚本”中运行,据我所知,它似乎在主线程中运行。
非常感谢你。
注:是的,我确实检查了所有其他关于软锁定的线程,但它们似乎都在问为什么会发生软锁定,而我知道原因,并希望有一种方法来防止它们。
P.P.S.:优化程序(使其运行更短)并不是一个真正的解决方案,因为我正在处理一个29GB的bz2文件,该文件以大约每秒10-40MB的速度在一个线程上提取到大约400GB的xml,所以即使是在最高速度下,我也会被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)
,它似乎不一定依赖于计时器时差-linux man pages for nanosleep状态,如果请求的间隔低于时钟粒度,它将被舍入到时钟粒度,这在linux上取决于根据手册页的时钟单调性。因此,0纳秒的值是完全有效的,并且应该始终有效,因为时钟粒度永远不能为0。希望这也能帮助别人;)
关于c - 如何防止C语言中的Linux软锁定/无响应而无需 sleep ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18736548/