通过多个线程访问vector

Accessing vector over multiple threads?

本文关键字:访问 vector 线程      更新时间:2023-10-16

如何保护矢量v不崩溃?另一个问题是,为什么它还没有崩溃,不是吗?

#include <Windows.h>
#include <thread>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
vector<int> v;
void a()
{
    while (true)
    {
        v.push_back(1);
        Sleep(100);
    }
}
void b()
{
    while (true)
    {
        if (!v.empty())
        {
            v.erase(v.begin());
        }
        Sleep(100);
    }
}
void c()
{
    while (true)
    {
        v.push_back(1);
        Sleep(100);
    }
}
int main()
{
    thread(&a).detach();
    thread(&b).detach();
    thread(&c).detach();
    while (true)
    {
        for (int i = 0; i < v.size(); i++)
        {
            v[i]++;
        }

        cout << v.size() << endl;

        if (!v.empty())
            v.erase(v.begin());
        Sleep(100);
    }
}

要从多个线程访问一个向量,需要添加std::互斥锁,惯用的方法是实现RAII,参见下面的演示代码:

#include <mutex>
#include <thread>
class raii_vector
{
public:
  raii_vector() {  }
  void Add() 
  { 
    std::lock_guard<std::mutex> lock(m_);
    v_.push_back(1);
  }
  void Remove() 
  { 
    std::lock_guard<std::mutex> lock(m_);
    if (!v_.empty())
    {
        v_.erase(v_.begin());
    }
  }
private:
  std::mutex       m_;
  std::vector<int> v_;
};
raii_vector rv;
void a()
{
  while (true)
  {
    rv.Add();
    std::cout << "adding " << std::endl;
    std::chrono::milliseconds dura( 100 );
    std::this_thread::sleep_for( dura );
  }
}
void b()
{
  while (true)
  {
    std::cout << "removing " << std::endl;
    rv.Remove();
    std::chrono::milliseconds dura( 100 );
    std::this_thread::sleep_for( dura );
  }
}
int main(int argc, char* argv[])
{
  std::thread t1(a);
  std::thread t2(b);
  t1.join();
  t2.join();
  return 0;
}

当想要使用数据结构时,例如来自多个线程的向量,我发现英特尔线程构建块库非常有用。