Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在没有睡眠的情况下防止C中的linux软锁定/无响应_C_Loops_Freeze - Fatal编程技术网

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

如何在没有睡眠的情况下防止C中的linux软锁定/无响应,c,loops,freeze,C,Loops,Freeze,在C程序中,如何正确地防止长时间运行的while循环中出现软锁定/无响应 dmesg报告软锁定 伪代码如下所示: while( worktodo ) { worktodo = doWork(); } 我的代码当然要复杂得多,还包括一个printf语句,它每秒执行一次以报告进度,但问题是,程序此时不再响应ctrl+c 我已经尝试过一些有用的方法,但我想要一个替代方法: 每次循环迭代执行printf都不知道为什么,但程序会以这种方式再次响应???-由于不必要的printf调用而浪费大量性能每个

在C程序中,如何正确地防止长时间运行的while循环中出现软锁定/无响应

dmesg报告软锁定

伪代码如下所示:

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,并因此产生了一个上下文切换。也许你想回答另一个问题?