【问题标题】:Why isn't usleep working?为什么睡眠不工作?
【发布时间】:2012-08-27 17:15:24
【问题描述】:

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

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

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

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

手册页将错误描述为:

[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 开发应用程序。

【问题讨论】:

    标签: objective-c macos cocoa unix system-calls


    【解决方案1】:

    usleepsleep 可以通过这种方式被信号传递中断。

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

    注意下面留下的原始答案在 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);
    

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

    【讨论】:

    • 这可能有效(但我怀疑它是否是调试器),但它并没有真正回答 OP 的问题。真正的问题是为什么它一开始就不起作用?它应该可以工作。
    • 呵呵,在调试器下运行好像有4个中断。即使使用信号阻塞代码,它也不起作用。我将重构答案以使用 nanosleep 技巧。
    【解决方案2】:

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

    即只有在确定呼叫失败时才能查看errno

    任何一个调用都不太可能失败。极不可能。


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

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

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

    • 您使用的是 lldb 吗?您是否尝试过切换到 gdb?

    【讨论】:

    • 我知道这一点。但是在这种情况下,调用 did 失败。失败时,usleep() 返回 -1。我检查了返回值;它的 -1。
    • 您的问题,措辞并不表示。很公平。
    • 我在调试器之外尝试过,但仍然遇到相同的错误。我没有任何信号繁重的代码,我正在使用 gdb。
    • OK -- 在做任何事情之前尝试usleep() in main()。然后在独立程序中尝试。您的应用中的信号发生了非常奇怪的情况。
    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 2016-12-14
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多