什么可以使macOS X 10.9上的纳米睡眠漂移10秒

时间:2014-04-01 11:44:25

标签: c++ macos boost osx-mavericks

我的程序的一部分需要睡眠10毫秒。通常我会使用boost lib,但它有时会睡眠10010毫秒,所以我尝试更换

boost::this_thread::sleep_for(boost::chrono::milliseconds(read_delay_ms));

struct timespec a;
a.tv_sec  = 0;
a.tv_nsec = read_delay_ms * 1000000;
int rc = nanosleep( &a, NULL );

毫无疑问,使用nanosleep有时也会睡眠10010毫秒(sleep_for是在mac上使用nanosleep()实现的。)

我的程序很复杂,所以我无法创建一个说明问题的小例子,我正在研究这个问题。以下是一些亮点:

  • 这是一个用C ++编写的python扩展,使用boost :: python作为桥接

  • 使用boost :: asio

  • 使用boost :: threads进行异步任务

该问题仅出现在mac OS X 10.9上。在Mac OS X 10.8及更低版本中没有出现,在linux,win,iOS和android上都看不到。

为了在我的代码,升级lib或sys函数中找到错误,任何帮助或建议都更受欢迎。

2 个答案:

答案 0 :(得分:4)

App Nap很可能就是这个原因。它是在10.9中引入的,并且因引起这样的惊喜而闻名。

NSProcessInfo有三种临时禁用App Nap的方法:beginActivityWithOptions:reason:endActivity:performActivityWithOptions:reason:block:

您也可以通过将boolean YES写入应用程序域的NSAppSleepDisabled用户默认值来禁用它。

答案 1 :(得分:1)

这是一个用C编写的程序化解决方案,它将在较旧和较新的OS X版本上编译和运行(即您不需要10.9或在Objective C中进行编译)。

在程序开始时调用osx_latencycritical_start(),或者至少在关键操作开始之前调用osx_latencycritical_end()。 如果您的代码不再执行时间关键工作,请致电#if defined(__APPLE__) #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 # include <objc/runtime.h> # include <objc/message.h> #else # include <objc/objc-runtime.h> #endif /* Globals */ static int osx_latencycritical_count = 0; static id osx_latencycritical_activity = nil; /* Tell App Nap that this is latency critical */ void osx_latencycritical_start() { Class pic; /* Process info class */ SEL pisl; /* Process info selector */ SEL bawo; /* Begin Activity With Options selector */ id pi; /* Process info */ id str; /* Reason string */ if (osx_latencycritical_count++ != 0) return; /* Avoid triggering an exception when run on older OS X */ if ((pic = (Class)objc_getClass("NSProcessInfo")) == nil) return; if (class_getClassMethod(pic, (pisl = sel_getUid("processInfo"))) == NULL) return; if (class_getInstanceMethod(pic, (bawo = sel_getUid("beginActivityWithOptions:reason:"))) == NULL) return; /* Get the process instance */ if ((pi = objc_msgSend((id)pic, pisl)) == nil) return; /* Create a reason string */ str = objc_msgSend(objc_getClass("NSString"), sel_getUid("alloc")); str = objc_msgSend(str, sel_getUid("initWithUTF8String:"), "Timing Crititcal"); /* Start activity that tells App Nap to mind its own business: */ /* NSActivityUserInitiatedAllowingIdleSystemSleep */ /* | NSActivityLatencyCritical */ osx_latencycritical_activity = objc_msgSend(pi, bawo, 0x00FFFFFFULL | 0xFF00000000ULL, str); } /* Done with latency critical */ void osx_latencycritical_end() { if (osx_latencycritical_count > 0) { osx_latencycritical_count--; if (osx_latencycritical_count == 0 && osx_latencycritical_activity != nil) { objc_msgSend( objc_msgSend(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")), sel_getUid("endActivity:"), osx_latencycritical_activity); osx_latencycritical_activity = nil; } } } #endif /* __APPLE__ */

(代码是递归安全的,但不是线程安全的。  我将此代码放在公共领域。)

// here is some block of code:
{
    FileReader file = new FileReader("C:/Users/John/Documents/key.txt");
    BufferedReader reader = new BufferedReader(file);

    // **** key is declared here in this block of code
    String key = "";
    String line = reader.readLine();

    while (line != null) {
        key += line;
        line = reader.readLine();
    }
    System.out.println(key); // so key works
}

// but here, the key variable is not visible as it is **out of scope**
String encryptedMsg = encrypt(message, key);