gpt4 book ai didi

c++ - 线程安全队列是一种好方法吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:19:40 29 4
gpt4 key购买 nike

我正在寻找一种方法来优化我开发的开源项目的以下代码,或者通过将繁重的工作转移到另一个线程来 boost 它的性能。

void ProfilerCommunication::AddVisitPoint(ULONG uniqueId)
{
CScopedLock<CMutex> lock(m_mutexResults);
m_pVisitPoints->points[m_pVisitPoints->count].UniqueId = uniqueId;
if (++m_pVisitPoints->count == VP_BUFFER_SIZE)
{
SendVisitPoints();
m_pVisitPoints->count=0;
}
}

以上代码被OpenCover使用profiler(一个用 C++ 编写的用于 .NET 的开源代码覆盖工具)在每个访问点被调用时。互斥量用于保护一些共享内存(在多个 32/64 位和 C++/C# 进程之间共享的 64K block ),当它已满时它会向主机进程发出信号。显然,这对每个检测点来说都很重,我想让影响更轻。

我正在考虑使用由上述方法推送到的队列和一个线程来弹出数据并填充共享内存。

问。我可以使用 C++ (Windows STL) 中的线程安全队列,还是无锁队列,因为我不想用一个问题替换另一个问题?人们认为我的方法明智吗?


编辑 1:我刚刚在 include 文件夹中找到了 concurrent_queue.h - 这可能是我的答案......?

最佳答案

好的,我会添加我自己的答案 - concurrent_queue 工作得很好

使用此 MSDN article 中描述的详细信息我实现了并发队列(和任务以及我的第一个 C++ lambda 表达式 :))我没有花很长时间思考,因为它是一个峰值。

inline void AddVisitPoint(ULONG uniqueId) { m_queue.push(uniqueId); }

...
// somewhere else in code

m_tasks.run([this]
{
ULONG id;
while(true)
{
while (!m_queue.try_pop(id))
Concurrency::Context::Yield();

if (id==0) break; // 0 is an unused number so is used to close the thread/task
CScopedLock<CMutex> lock(m_mutexResults);
m_pVisitPoints->points[m_pVisitPoints->count].UniqueId = id;
if (++m_pVisitPoints->count == VP_BUFFER_SIZE)
{
SendVisitPoints();
m_pVisitPoints->count=0;
}
}
});

结果:

  • 没有检测的应用程序 = 9.3
  • 使用旧检测处理程序的应用程序 = 38.6
  • 具有新检测处理程序的应用程序 = 16.2

关于c++ - 线程安全队列是一种好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7242916/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com