1

我有一个在单独的队列/线程上运行的函数。在这个函数中,我试图调用usleep.

无论传入的值如何,usleep似乎都不起作用。也是如此sleep()

为了诊断错误,我打印了errno. errno打印为:“中断的系统调用”

这到底是什么意思,我该如何诊断它?

手册页将错误描述为:

[EINTR]            A signal was delivered to the process and its action was to invoke a signal-catching
                    function.

注意我在使用 Xcode 4 和 Objective-C 的 OSX Mountain Lion 上。我正在使用 Cocoa 为 OSX 开发应用程序。

4

2 回答 2

4

usleep并且sleep可以通过传递信号以这种方式中断。

没有专用的信号传递线程,因此可以将信号传递到应用程序中的任意线程。

注意下面留下的原始答案在 Mountain Lion 上无法正常工作 - 在 XCode 下运行时会触发 EINTR。

为了避免这个问题,我们切换到nanosleep,并使用这样一个事实,即当它被中断时,它会在第二个参数中返回剩余时间:

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

虽然,如果您使用的是 NSThread,那么您最好使用:

[NSThread sleepForTimeInterval:1.0f]; // sleep for 1 second

这是可可的睡眠方式,不会受到“打嗝”的影响sleepusleepnanosleep经验

旧答案- 在调试器下无法正常工作。

如果你想防止你的线程usleep被中断,你需要屏蔽掉所有可能传递给线程的信号。例如

#include <signal.h>

sigset_t sigset;
sigset_t oldset;
sigfillset(&sigset);
pthread_sigmask(SIG_BLOCK, &sigset, &oldset);
usleep(9999);
pthread_sigmask(SIG_SETMASK, &oldset, NULL);

注意:此代码中未进行错误检查

于 2012-09-03T07:28:33.810 回答
0

你不能errno在任何时候随意打印并期望它有用。它是一个每个线程的变量,只有在特定的系统调用设置它之后才会设置。

即,您只能errno在确定呼叫失败时进行检查。

任何一个呼叫都不太可能失败。极不可能。


从您的问题中不清楚您正在获取返回值。

  • 在调试器之外尝试它,它可能是调试器用信号冲洗东西。如果是这样,它很可能是一个错误。

  • 您还有其他信号量大的代码或子系统在使用吗?一般来说,信号处理程序在 Unix 系统上很麻烦。

  • 你在使用lldb吗?你试过切换到gdb吗?

于 2012-09-03T00:51:10.680 回答