为什么某些函数可以将 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" 会被打印出来。所以程序结束得很快,我没注意到引擎是否工作。
我发现:
- 如果我将 sleep() 替换为 getchar() 引擎将正常工作。
- 如果我将主动等待置于 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));
当然,此解决方案不适用于需要精确睡眠量的应用程序,但在执行下一个功能之前需要最小延迟的情况下非常有用。
我在 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" 会被打印出来。所以程序结束得很快,我没注意到引擎是否工作。
我发现:
- 如果我将 sleep() 替换为 getchar() 引擎将正常工作。
- 如果我将主动等待置于 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));
当然,此解决方案不适用于需要精确睡眠量的应用程序,但在执行下一个功能之前需要最小延迟的情况下非常有用。