【问题标题】:c++11 multithreading issues with Android where some threads are not scheduled properlyc++11 与 Android 的多线程问题,其中某些线程未正确调度
【发布时间】:2014-12-12 07:56:28
【问题描述】:

我正在开发一个基于 VoIP 的多线程应用程序。对于每个套接字,都有一个 c++11 std::thread(包括 SSL 读写)。数据通信的核心模块是C++语言,通过JNI接口调用。

我的观察是,一旦在几秒钟后初始化应用程序,一些之前正常运行的线程没有得到运行时间。如果某个线程正在运行,那么它会持续运行一段时间,从 3-4 秒到 30-40 秒不等。

在引用change native thread priority on Android 之后,我还尝试将所有线程的“nice”值更改为-10,但没有成功。 需要注意的是,完全相同的 C++ 代码在 iOS 上运行得非常好。

Android Native 线程调度有问题,还是我遗漏了什么?

【问题讨论】:

  • 我们在 Android 测试运行 (ARM) 中使用了相当多的线程,我不知道那里有任何特殊问题。我怀疑您的应用程序正在做一些“不符合规则”的事情(或有不正确/未定义的期望)。
  • @MatsPetersson,有可能。在 iOS 和 Android 中,与 C++ 的接口是不同的。我们还有套接字(和 PJSIP),它们的行为可能会根据平台或编写的代码而有所不同。这是否意味着,所提到的问题不是问题?
  • 你能得到堆栈跟踪吗?当线程没有运行时,它们在哪里?我想知道区别是否在于 I/O 处理而不是线程调度之类的东西。在最新版本的 Android 上,使用已获得根设备的设备,您可以使用 debuggerd -b <pid> 转储线程。
  • 在某些地方显然存在问题,但在很多可能的情况下,它要么是 Android 操作系统之上的一层,要么是您自己的代码的某些部分,无法正常工作。也就是说“你需要弄清楚发生了什么,但 Android 本身的线程不太可能被破坏,而带有 C++ std::thread 的 Android 也不太可能被破坏”。这有点像说“我的代码不起作用int x = 42; printf("%f\n", x);,printf b0rked 吗?” - 如果您使用的是基础服务(并且 std::thread 和 android 操作系统的线程是基础的),则不太可能出现问题。
  • @MatsPetersson,我已通过修复 1 个竞态条件来修复线程相关问题。然而,语音问题仍然没有完全解决。我们使用 PJSIP 作为内部 SIP 堆栈。有时语音质量很好,有时很差。在日志中,当我们看到数据包流动时,我们看不到“好”和“坏”调用之间有任何区别。

标签: android c++ multithreading c++11 android-ndk


【解决方案1】:
while (...) {
 int selectResult = select( fd, ...);
 if ( selectResult > 0 ) DoSomeWork( fd );
 else nanosleep(...); /* this is the new line which solved my stalling threads */
}

我有一个类似的问题,并发现对于我的情况,解决方案是验证那些具有永恒循环的线程(不断执行选择,直到套接字上有东西产生处理程序线程),总是调用 nanosleep在他们的循环中至少一次。

和你一样,我在 Android 上遇到了这个问题,在 iOS 上没有问题。

我只能假设 Android 上的 JVM 有时会给一个线程完全优先级,该线程只轮询一个套接字而不暂停,这样其他有实际工作要做的线程就会停止。但我不知道如何验证这个假设。

鉴于 select 已经使用了用户选择的超时,我的解决方案也很奇怪,因此我认为它无论如何都会在内部休眠。显然不在 Android 上。

【讨论】:

    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多