加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 06:57:21 所属栏目:百科 来源:网络整理
导读:我正在寻找一种优化以下代码的方法,对于我开发的开源项目,或者通过将繁重的工作移动到另一个线程来使其更高效. void ProfilerCommunication::AddVisitPoint(ULONG uniqueId){ CScopedLockCMutex lock(m_mutexResults); m_pVisitPoints-points[m_pVisitPoints
我正在寻找一种优化以下代码的方法,对于我开发的开源项目,或者通过将繁重的工作移动到另一个线程来使其更高效.

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分析器(用C编写的.NET的开源代码覆盖工具)使用.互斥锁用于保护某些共享内存(在多个进程32/64位和C/C++#之间共享的64K块),当它充满时它会向主机进程发出信号.显然,对于每个仪表点而言,这都非常重,我想使影响更轻.

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

问:我可以使用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读