为什么某些函数可以将 sleep(n) 减少为 sleep(0)?

Why some function could reduce sleep(n) into sleep(0)?

我在 C 中遇到了一个非常奇怪的问题。专有库中的一个函数将 sleep(n) 减少为 sleep(0)。

我的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>  /*sleep() */

int main(int argc, char** argv){
   //...
   AStreamEngine.init();
   AStreamEngine.setCodec(3);

   AStreamEngine.start(); //problematic function

   printf("a");
   sleep(100);
   printf("b");
   return 0;
}

如果有问题的函数被注释掉,然后打印 "a",然后在 100 秒后打印 "b"。但是如果没有被注释掉,"ab" 会被打印出来。所以程序结束得很快,我没注意到引擎是否工作。

我发现:

  1. 如果我将 sleep() 替换为 getchar() 引擎将正常工作。
  2. 如果我将主动等待置于 for 循环中,那么它也可以工作。

有人知道为什么会这样吗?以及如何修复(绕过)这个 feature/bug?我不想使用 getchar 和主动等待。

更新: 我没有图书馆的来源。我只有二进制 .so 文件。

根据回复,我添加了以下代码添加结束:

struct timespec to_sleep = { 1, 0 }; 
int ret = nanosleep(&to_sleep,&to_sleep);
printf("%d\n",ret);
if(ret == -1){
    printf(" break sleep : %d %s", errno,strerror(errno));
}

我得到输出:

-1
break sleep : 4 Interrupted system callc

现在尝试线程绕过

"sleep" 可以被信号中断 - 参见 http://man7.org/linux/man-pages/man3/sleep.3.html 。我的猜测是 "start" 函数启动了一个线程,该线程可能导致将信号发送到您的程序。将 "sleep" 放入这样的循环中:

 unsigned int x = 100;
 while (x > 0) { x = sleep (x); }

还有一点:printf 可能是行缓冲的。在该模式下,仅当您打印“\n”字符时才会看到输出。尝试使用 "a\n".

经过检查,我认为使用 sleep() 函数对你的情况没有用。

事实上,睡眠函数使用 pause() 函数,它等待信号并在您的进程收到信号调用时停止。

在您的情况下,这可能是问题所在,它解释了为什么在您调用 AStreamEngine.start()[ 时 sleep() 函数停止的原因=27=]函数。

我认为最好的解决方案是使用 usleep() 函数,如果您的进程收到信号,该函数不应停止。

试试这个:

usleep(VALUE_IN_MILISECONDS);

祝你好运! :)

正如 Jack 所说的那样,usleep 和 sleep 可以被信号的传递中断(例如,ioctl 的存在、读、写函数调用)。

避免此问题的明智方法之一是使用 nanosleep。与 sleep 和 usleep 一样,nanosleep 也可以被信号的传递打断,但不同的是,它的第二个参数告诉你还剩多少时间。

您可以使用此参数来确保您的代码休眠指定的时间。用包含 nanosleep 的 while 循环替换您的 sleep 和 usleep 函数。以下是示例用法,

struct timespec to_sleep = { 1, 0 }; // Sleep for 1 second
while ((nanosleep(&to_sleep, &to_sleep) == -1) && (errno == EINTR)); 

当然,此解决方案不适用于需要精确睡眠量​​的应用程序,但在执行下一个功能之前需要最小延迟的情况下非常有用。