如何确定性地使用 std::this_thread::yield()

How to use std::this_thread::yield() deterministically?

本文关键字:this thread yield std 确定性      更新时间:2023-10-16

在开发基于VoIP的应用程序时,我们有一个通用的多线程C++11模块。它在iOS,MacOS中运行良好,但在Android中发现线程调度困难。

可选设计说明(仅当有兴趣时(

我很少有线程使用消息队列运行。

  1. 主(将数据写入队列中接收SSL_Read套接字(
  2. SSL_Read(从 SSL 读取数据并更新其队列(
  3. SSL_Write(将数据写入直接从套接字线程接收的SSL(
  4. 每个套接字
  5. 的线程数(从套接字读取数据并发送到SSL_Write队列(

1-2 是相关的,3-4 是相关的。
我观察到在许多调用期间,只有 2 个线程在活动运行,其他 2 个线程没有运行时间。因此观察到 1 路语音路径。

问题

我怀疑这是Android Linux的问题,为此,我已经有一篇未回答的帖子:
Android 的 c++11 多线程问题,其中某些线程未正确调度。
通过标准::this_thread::yield((使用?

目标是为所有线程提供类似的时间切片。已尝试以下选项:

  1. 我决定std::thread::yield()在消息队列填满超过一定限度;例如,来自 1 个线程的 10 条消息。我循环尝试yield() 1 次和 100 次,但没有它的优势。同一线程继续运行。
  2. 对于 0 和 100 毫秒sleep_for()选项也是如此。
  3. 尝试将所有线程nice()值更改为 -10、-20,但没有运气。

如何在不消耗太多 CPU 周期的情况下有效地使用std::this_thread::yield()

std::this_thread::yield()什么都不做是合法的。它为调度程序提供了调度另一个线程的机会;调度程序不必利用它。

您可以尝试以下任一方法:

  1. 通过将工作打包到通用任务队列中,使每个线程能够处理需要执行的任何工作。这样,哪个线程承担工作并不重要,当有线程要做时,最重要的工作就会完成。

  2. 在线程之间添加同步,例如屏障机制(参见 boost 的屏障类(,以保持所有 4 个线程同步。