c++ - 确定时间关键循环中 200 毫秒卡住的原因

标签 c++ windows multithreading virtual-serial-port

问题的新描述:

我目前在测试环境中运行我们的新数据采集软件。该软件有两个主线程。一个包含与硬件通信并将数据推送到双缓冲区的快速循环。每隔几秒,这个循环就会卡住 200 毫秒。我做了几次测试,但没有一个让我弄清楚软件在等待什么。由于软件相当复杂,测试环境也可能会干扰软件,因此我需要一种工具/技术来测试记录器线程在被阻塞 200 毫秒时正在等待什么。什么工具有助于实现这一目标?

原始问题:

在我们的数据采集软件中,我们有两个提供主要功能的线程。一个线程负责从不同的传感器收集数据,第二个线程将数据以大块的形式保存到磁盘。数据收集在双缓冲区中。它通常包含每个项目 100000 个字节,每秒最多收集 300 个项目。一个缓冲区用于在数据收集线程中写入,一个缓冲区用于读取数据并在第二个线程中将其保存到磁盘。如果已读取所有数据,则切换缓冲区。缓冲区的切换似乎是一个主要的性能问题。每次缓冲区切换时,数据收集线程都会阻塞大约 200 毫秒,这太长了。然而,偶尔会发生这种情况,即切换速度要快得多,几乎不花时间。 (测试 PC:Windows 7 64 位,i5-4570 CPU @3.2 GHz(4 核),16 GB DDR3 (800 MHz))。

我的猜测是,性能问题与核心之间交换的数据有关。只有当线程偶然运行在同一个核心上时,交换才会快得多。我考虑过以强制两个线程在同一个内核上运行的方式设置线程关联掩码,但这也意味着我失去了真正的并行性。另一个想法是让缓冲区在切换之前收集更多数据,但这会大大降低数据显示的更新频率,因为它必须等待缓冲区切换才能访问新数据。

我的问题是:是否有一种技术可以在不干扰收集线程的情况下将数据从一个线程移动到另一个线程?

编辑:双缓冲区实现为两个用作环形缓冲区的 std::vectors。 bool (int) 变量用于告知哪个缓冲区是事件的写入缓冲区。每次访问双缓冲区时,都会检查 bool 值以了解应该使用哪个 vector 。切换双缓冲区中的缓冲区仅意味着切换此 bool 值。当然,在切换期间,所有读取和写入都被互斥锁阻止。我不认为这个互斥锁可能会阻塞 200 毫秒。顺便说一句,对于每个开关事件,200 毫秒的重现性非常好。

最佳答案

仅仅为了切换一个 bool 变量而锁定和释放互斥量不会花费 200 毫秒。

主要问题可能是两个线程以某种方式相互阻塞。 这种阻塞称为lock contention .基本上,只要一个进程或线程试图获取另一个进程或线程持有的锁,就会发生这种情况。取而代之的是并行性,您有两个线程等待彼此完成他们的部分工作,其效果与单线程方法类似。

为了进一步阅读,我推荐 this阅读文章,更详细地描述了锁争用。

关于c++ - 确定时间关键循环中 200 毫秒卡住的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26887403/

相关文章:

c++ - 递归宏传播的结果是什么?

c++ - 使#include <header.h> 仅对其自己的库可见

python - 运行时出现语法错误 "yolk -l"

java - 如何在向另一个应用程序发送数据时实现重试策略?

ios - 从 NSTimer 回到主线程

java - 使用线程点击 url

c++ - 解释 Valgrind 内存泄漏摘要日志

c++ - linux 标准输出管道问题

c - 在 Windows 上,spawnl 返回 EINVAL

.net - Windows 客户端损坏授权 header (Kerberos) => IIS 400(错误请求)