如何在没有睡眠的情况下防止C中的linux软锁定/无响应
在C程序中,如何正确地防止长时间运行的while循环中出现软锁定/无响应 dmesg报告软锁定 伪代码如下所示:如何在没有睡眠的情况下防止C中的linux软锁定/无响应,c,loops,freeze,C,Loops,Freeze,在C程序中,如何正确地防止长时间运行的while循环中出现软锁定/无响应 dmesg报告软锁定 伪代码如下所示: while( worktodo ) { worktodo = doWork(); } 我的代码当然要复杂得多,还包括一个printf语句,它每秒执行一次以报告进度,但问题是,程序此时不再响应ctrl+c 我已经尝试过一些有用的方法,但我想要一个替代方法: 每次循环迭代执行printf都不知道为什么,但程序会以这种方式再次响应???-由于不必要的printf调用而浪费大量性能每个
while( worktodo ) {
worktodo = doWork();
}
我的代码当然要复杂得多,还包括一个printf语句,它每秒执行一次以报告进度,但问题是,程序此时不再响应ctrl+c
我已经尝试过一些有用的方法,但我想要一个替代方法:
每次循环迭代执行printf都不知道为什么,但程序会以这种方式再次响应???-由于不必要的printf调用而浪费大量性能每个doWork调用不会花费很长时间
使用sleep/usleep/…-对我来说,这似乎也是在浪费处理时间,因为整个程序已经全速运行了几个小时
我想的是某种进程等待事件函数之类的,正常信号似乎工作正常,因为我可以在不同的shell上使用kill来停止程序
其他背景信息:我正在使用,我的代码运行在main.c维护脚本中,据我所知,它似乎运行在主线程中
多谢各位
附言:是的,我确实检查了我发现的所有其他关于软锁定的线程,但它们似乎都在问为什么会发生软锁定,而我知道为什么会发生软锁定,并且希望有一种方法来防止它们
p.p.S.:优化程序使其运行更短并不是一个真正的解决方案,因为我正在处理一个29GB的bz2文件,该文件以每秒10-40MB的速度在单个线程上提取约400GB的xml,因此,即使在最高速度下,我也会受到I/O的约束,并且仍会让它运行几个小时。您的场景并不是真正的软锁定,而是一个进程正在忙着做一些事情 这个伪代码怎么样:
void workerThread()
{
while(workToDo)
{
if(threadSignalled)
break;
workToDo = DoWork()
}
}
void sighandler()
{
signal worker thread to finish
waitForWorkerThreadFinished;
}
void main()
{
InstallSignalHandler;
CreateSemaphore
StartThread;
waitForWorkerThreadFinished;
}
虽然使用线程提出的答案可能是一种选择,但实际上它只是将问题转移到另一个线程。我的解决方案毕竟是使用
sleep(0)
还测试了sched_yield/pthread_yield,这两种方法都没有真正的帮助。不幸的是,我一直无法找到一个好的资源来记录linux中的sleep0,但是对于windows来说,使用值0可以让线程产生当前cpu片的剩余部分
事实证明,sleep0最有可能依赖于linux中所谓的计时器松弛-有关这方面的文章可以在这里找到:
另一种可能是使用nanosleep&struct timespec{0},NULL,它似乎不一定依赖于计时器的空闲时间-声明如果请求的间隔低于时钟粒度,它将被舍入到时钟粒度,而在linux上,根据手册页,时钟粒度取决于时钟的单调性。因此,0纳秒的值是完全有效的,并且应该始终有效,因为时钟粒度永远不能为0
希望这对其他人也有帮助 显然是时间问题。使用信号机制应该可以解决问题
printf的使用解决了这个问题,因为printf访问控制台是一个昂贵且耗时的过程,在您的情况下,它为工作人员提供了足够的时间来完成其工作。工作循环应该在一个辅助线程中,在循环开始时,检查一个信号量以查看是否应该退出循环。在main中,您可以创建一个信号处理程序来处理ctrl+c,它应该设置信号量并等待。然后,Main将只是等待worker循环发出它已完成的信号。我确实在dmesg中收到软锁定消息,这确实是一个问题,因为程序将频繁执行,并且滥发sys日志也不是很好。对于工作线程建议:在这种情况下,工作线程syslog消息中不会出现相同的软锁定问题吗?dmesg中的软锁定建议出现内核/驱动程序问题,而不是用户模式问题。dmesg将程序声明为软锁定的源-在这种情况下,它仍然可能是内核/驱动程序问题吗?顺便说一句,我使用的是gwan app server,对程序没有完全控制权,但我的c维护脚本main.c似乎在主线程中运行。虽然我不是投反对票的人,但你的答案既没有帮助,也不适用。我只有一个线程,没有工作线程。另外,我现在知道printf最有可能工作的原因是它产生了一个sycall,并因此产生了一个上下文切换。也许你想回答另一个问题?