Objective c 为什么usleep不起作用?

Objective c 为什么usleep不起作用?,objective-c,macos,cocoa,unix,system-calls,Objective C,Macos,Cocoa,Unix,System Calls,我有一个在单独队列/线程上运行的函数。在这个函数中,我试图调用usleep 不管传入的值是多少,usleep似乎都不起作用。睡眠也是如此 为了诊断错误,我打印了errno。errno打印为:中断的系统调用 这到底意味着什么?我该如何诊断它 手册页将错误描述为: [EINTR] A signal was delivered to the process and its action was to invoke a signal-catching

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

不管传入的值是多少,usleep似乎都不起作用。睡眠也是如此

为了诊断错误,我打印了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。我正在为OSX开发一个使用Cocoa的应用程序。

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

也就是说,只有在确定呼叫失败时,才能检查errno

这两个调用都不太可能失败。极不可能

从您的问题中不清楚您是否在获取返回值

在调试器之外尝试它,它可能是调试器使用信号处理东西。如果是这样,那很可能是一个bug

您是否有其他信号密集型代码或子系统在起作用?一般来说,Unix系统上的信号处理程序都很糟糕

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


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

也就是说,只有在确定呼叫失败时,才能检查errno

这两个调用都不太可能失败。极不可能

从您的问题中不清楚您是否在获取返回值

在调试器之外尝试它,它可能是调试器使用信号处理东西。如果是这样,那很可能是一个bug

您是否有其他信号密集型代码或子系统在起作用?一般来说,Unix系统上的信号处理程序都很糟糕

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

usleep和睡眠可以通过发送信号以这种方式中断

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

注意,下面留下的原始答案在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
这是一种可可式的睡眠方式,而且不受睡眠、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);
注意:此代码中未进行错误检查。

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
这是一种可可式的睡眠方式,而且不受睡眠、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);

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

我知道这一点。然而,在这种情况下,呼叫确实失败了。失败时,usleep返回-1。我检查了返回值;你的问题,用词来说,并没有表明这一点。很公平。我在调试器之外尝试了它,但仍然得到了相同的错误。我没有任何信号密集的代码,我正在使用gdb.OK-在做任何事情之前,在main中尝试usleep。然后在独立程序中尝试。你的应用程序中出现了一些非常奇怪的信号。我知道这一点。然而,在这种情况下,呼叫确实失败了。失败时,usleep返回-1。我检查了返回值;你的问题,用词来说,并没有表明这一点。很公平。我在调试器之外尝试了它,但仍然得到了相同的错误。我没有任何信号密集的代码,我正在使用gdb.OK-在做任何事情之前,在main中尝试usleep。然后在独立程序中尝试。你的应用程序中出现了一些非常奇怪的信号。这可能会起作用,但我怀疑它是否是调试器,但它并没有真正回答OP的问题
. 真正的问题是为什么它一开始就不起作用?它应该可以工作。嗯,在调试器下运行时似乎有4次中断。即使使用信号阻塞代码,它也无法工作。我将重构答案以使用nanosleep技巧。这可能有效,但我怀疑它是否是调试器,但它并没有真正回答OP的问题。真正的问题是为什么它一开始就不起作用?它应该可以工作。嗯,在调试器下运行时似乎有4次中断。即使使用信号阻塞代码,它也无法工作。我将重构答案以使用nanosleep技巧。