0

ベクトル v がクラッシュしないようにするにはどうすればよいですか? もう 1 つの質問ですが、なぜまだクラッシュしていないのでしょうか?

#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);
    }
}
4

2 に答える 2

1

複数のスレッドから 1 つのベクトルにアクセスするには、std::mutex を追加する必要があります。慣用的な方法は 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;
}
于 2013-01-08T09:35:49.223 に答える
0

複数のスレッドからのベクトルなどのデータ構造を使用したい場合、Intel Threading Building Blocks ライブラリが非常に役立つことがわかりました。

于 2013-01-08T09:55:04.687 に答える