【发布时间】:2022-02-03 21:39:01
【问题描述】:
这是一个使用线程测试循环调用的小 C++ 代码。但有时会因为意外延迟而失败。应该每 10 毫秒调用一次 for 循环。 for-loop 的运行时间通常只有 1ms。但有时执行时间会超过 200ms。看起来其他进程中断了这个 for 循环并在 200 毫秒后返回。这太不可思议了,200ms,这么长的时间。该程序在 GNU Linux 5.10.41 ARM aarch64 下运行。 我该怎么做,使主线程不能被其他进程或线程抢占?非常感谢!
while(1)
{
auto start_time = std::chrono::high_resolution_clock::now();
LOG_F(INFO, "cyclic start time");
for(int j = 0; j < 150000; j++); //
auto end_time = std::chrono::high_resolution_clock::now();
auto exec_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
LOG_F(INFO, "execution time: %dms", exec_time.count());
if (exec_time.count() < 10)
{
LOG_F(INFO, "i = %d", i);
std::this_thread::sleep_for(std::chrono::milliseconds(10 - exec_time.count()));
}
else
{
LOG_F(ERROR, "execution time was higher than 10ms (%dms)", exec_time.count());
break;
}
}
【问题讨论】:
-
您可以尝试使用更高优先级的线程或实时线程。这些不太可能被窥视。但是通常如果您的系统不是处于重负载下,您的程序不应被抢占 200 毫秒
-
for(int j = 0; j < 150000; j++);的目的是什么?它将被优化掉。您只是在衡量日志记录功能的时间成本。 -
在黑暗中拍摄。记录互斥量。您的日志记录系统中可能存在互斥锁/锁。另一个线程可能是资源占用者,它获取了锁并且没有快速释放它。这将导致 THIS 线程等待比预期更长的时间。通过禁用所有其他线程来检查此行为并查看行为是否继续。
-
快速测试,将所有日志记录语句移到捕获
start_time和end_time的位置之外。如前所述,如果您希望for循环执行任何操作,请确保您正在编译没有优化。但即使数到 150000 也应该非常快,可能在微秒数量级。 -
非常感谢您的建议。执行了 for 循环,没有优化。在日志文件中更改运行时的循环号也不同。该程序在具有 4 个处理器的 S32G EVB 上运行。使用 top 命令我可以看到 CPU 负载 = 4.3%。即使使用了代码中的线程函数 sleep(),但实际上只有一个主线程。
标签: c++ linux multithreading