C++11 C++;11:无锁迭代时如何防止向量循环更新

C++11 C++;11:无锁迭代时如何防止向量循环更新,c++11,timer,C++11,Timer,我的应用程序中有计时器,每100ms回调一次它的函数 使用: m_global_connections向量填充到应用程序none stop中 所以每次计时器回调我都会复制与这个时间点相关的元素,我知道它效率不高,但我没有找到更好的方法, 问题是 当计时器再次调用且循环未完成但从中得到更新时会发生什么 con_list m_connectionsLocalTmp = m_global_connections; 现在它正在循环新的元素集。 如何在回调中对该逻辑进行排序?您确实需要使用互斥锁或基于a

我的应用程序中有计时器,每100ms回调一次它的函数 使用:

m_global_connections向量填充到应用程序none stop中
所以每次计时器回调我都会复制与这个时间点相关的元素,我知道它效率不高,但我没有找到更好的方法, 问题是 当计时器再次调用且循环未完成但从中得到更新时会发生什么

con_list m_connectionsLocalTmp = m_global_connections;
现在它正在循环新的元素集。

如何在回调中对该逻辑进行排序?

您确实需要使用互斥锁或基于at原子变量的自旋锁进行锁定。 更好的方法是使用两个向量并相应地交换它们。 在本例中,为了简单起见,我使用了互斥

    con_list m_connectionsLocalTmp;
    //copy the members which are relevant in this point in time
    {
      std::lock_guard<std::mutex> lock(g_i_mutex);
      while(!connectionsLocalTmp.empty()){ }
      std::swap(connectionsLocalTmp, m_global_connections);
    }
    for (const auto it : m_connectionsLocalTmp )
    {
       ...
       ...
    }
con_list m_connectionsLocalTmp;
//及时复制与此相关的成员
{
std::锁定保护锁(g_i_互斥锁);
而(!connectionsLocalTmp.empty()){}
交换(连接本地TMP、m_全局_连接);
}
for(const auto it:m_connections localtmp)
{
...
...
}

您确实需要使用互斥锁或基于at原子变量的自旋锁进行锁定。 更好的方法是使用两个向量并相应地交换它们。 在本例中,为了简单起见,我使用了互斥

    con_list m_connectionsLocalTmp;
    //copy the members which are relevant in this point in time
    {
      std::lock_guard<std::mutex> lock(g_i_mutex);
      while(!connectionsLocalTmp.empty()){ }
      std::swap(connectionsLocalTmp, m_global_connections);
    }
    for (const auto it : m_connectionsLocalTmp )
    {
       ...
       ...
    }
con_list m_connectionsLocalTmp;
//及时复制与此相关的成员
{
std::锁定保护锁(g_i_互斥锁);
而(!connectionsLocalTmp.empty()){}
交换(连接本地TMP、m_全局_连接);
}
for(const auto it:m_connections localtmp)
{
...
...
}

正如@dau_sama所述,您需要一个来自
互斥锁的锁。然而,我会使用内置的专业知识

Hacking@dau_sama示例:

con_list m_connectionsLocalTmp;
//copy the members which are relevant in this point in time
{
  std::lock_guard<std::mutex> lock(g_i_mutex);
  while(!connectionsLocalTmp.empty()){ }
  m_global_connections.swap(connectionsLocalTmp);
}
for (const auto it : m_connectionsLocalTmp )
{
   // ...
}
con_list m_connectionsLocalTmp;
//及时复制与此相关的成员
{
std::锁定保护锁(g_i_互斥锁);
而(!connectionsLocalTmp.empty()){}
m_global_connections.swap(connectionsLocalTmp);
}
for(const auto it:m_connections localtmp)
{
// ...
}

但是,我不会为此使用本机向量,而是使用
队列
容器适配器,并等待数据。这将消除交换、轮询循环,并按显示方式处理数据。

正如@dau_sama所述,您需要从
互斥锁中锁定。然而,我会使用内置的专业知识

Hacking@dau_sama示例:

con_list m_connectionsLocalTmp;
//copy the members which are relevant in this point in time
{
  std::lock_guard<std::mutex> lock(g_i_mutex);
  while(!connectionsLocalTmp.empty()){ }
  m_global_connections.swap(connectionsLocalTmp);
}
for (const auto it : m_connectionsLocalTmp )
{
   // ...
}
con_list m_connectionsLocalTmp;
//及时复制与此相关的成员
{
std::锁定保护锁(g_i_互斥锁);
而(!connectionsLocalTmp.empty()){}
m_global_connections.swap(connectionsLocalTmp);
}
for(const auto it:m_connections localtmp)
{
// ...
}

但是,我不会为此使用本机向量,而是使用
队列
容器适配器,并等待数据。这将消除交换、轮询循环,并按显示的方式处理数据。

为什么要使用队列而不是向量?为什么是条件变量?我还需要保持m_全局连接不变,因为它是应用程序的连接存储库。这更像是一个语义问题。我将传入的数据视为一个流,而更自然的查看方式是队列。虽然每100毫秒进行一次轮询并处理在最后十分之一秒内出现的所有内容都有效,但我觉得在数据到达时处理数据更为优雅。我也在一个100毫秒是很长时间的环境中工作!嗯,也许我和@dau_sama误解了你的问题。我们都认为您在处理数据,而不是更新数据。为什么要使用队列而不是向量?为什么是条件变量?我还需要保持m_全局连接不变,因为它是应用程序的连接存储库。这更像是一个语义问题。我将传入的数据视为一个流,而更自然的查看方式是队列。虽然每100毫秒进行一次轮询并处理在最后十分之一秒内出现的所有内容都有效,但我觉得在数据到达时处理数据更为优雅。我也在一个100毫秒是很长时间的环境中工作!嗯,也许我和@dau_sama误解了你的问题。我们都认为您在处理数据,而不是更新数据。为什么交换比将向量复制到向量更好?我还需要保持m_全局_连接的原样,因为它是应用程序的连接存储库
交换
更好,因为它交换两个指针。文档中说:“不会对单个元素调用任何移动、复制或交换操作。”为什么交换比将向量复制到向量更好?我还需要保持m_全局_连接的原样,因为它是应用程序的连接存储库
交换
更好,因为它交换两个指针。文档声明:“不会对单个元素调用任何移动、复制或交换操作。”