我有一个在单独的队列/线程上运行的函数。在这个函数中,我试图调用usleep
。
无论传入的值如何,usleep
似乎都不起作用。 sleep()
也是如此。
为了诊断错误,我打印出errno
。 errno
打印为:“系统调用中断”
这究竟是什么意思,我该如何进行诊断呢?
手册页将错误描述为:
[EINTR] A signal was delivered to the process and its action was to invoke a signal-catching
function.
注意我在OSX Mountain Lion上使用Xcode 4并使用Objective-C。我正在使用Cocoa为OSX开发一个应用程序。
答案 0 :(得分: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
这是可可的睡眠方式,并没有受到sleep
,usleep
和nanosleep
经历的“打嗝”的影响
旧答案 - 在调试器下无法正常工作。
如果要阻止使usleep
的线程被中断,则需要屏蔽可能传递给线程的所有信号。 e.g。
#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);
注意:此代码中未完成错误检查
答案 1 :(得分:0)
您无法随时随意打印errno
并希望它有用。它是一个每线程变量,只有在特定的系统调用设置它之后才能设置它。
即。您只能在确定呼叫失败后才能查看errno
。
两种呼叫都不太可能失败。极不可能。
从您的问题中不清楚您是否抓住了返回值。
在调试器外部尝试,它可能是调试器输入信号的东西。如果是这样,那可能就是一个错误。
您是否还有其他信号繁重的代码或子系统?一般来说,信号处理程序在Unix系统上很棘手。
你在使用lldb吗?你尝试过切换到gdb吗?