Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这样的类在多个线程的集合中只能读取一次吗?_C++_Multithreading_Oop_Boost_Locking - Fatal编程技术网

C++ 这样的类在多个线程的集合中只能读取一次吗?

C++ 这样的类在多个线程的集合中只能读取一次吗?,c++,multithreading,oop,boost,locking,C++,Multithreading,Oop,Boost,Locking,所以有一门课,比如: class mySafeData { public: mySafeData() : myData(0), changed( false ) { } void Set(int i) { boost::mutex::scoped_lock lock(myMutex); myData = i; // set the data changed = true; // mark as changed myCondvar.notif

所以有一门课,比如:

class mySafeData
{
public:
  mySafeData() : myData(0), changed( false )
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
    changed = true; // mark as changed
    myCondvar.notify_one(); // notify so a reader can process it
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    while( !changed )
    {
       myCondvar.wait( lock );
    } 
    i = myData;
    changed = false; // mark as read
    myCondvar.notify_one(); // notify so the writer can write if necessary
  }
 private:
   int myData;
   boost::mutex myMutex;
   boost::condition_variable myCondvar;
   bool changed;
};
循环中的一个线程调用
Set
。以及3个或更多线程调用
Get
如何让所有调用
Get
的线程实际获取数据(每个线程只需调用
Set
一次即可获取数据)(似乎只有第一个“读卡器”调用
Get
获取数据)

更新此选项可以吗?:

class mySafeData
{
public:
  mySafeData() : myData(0)
  {
  }

  void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    i = myData;

  }
 private:
   int myData;
   boost::mutex myMutex;
};

我认为您不需要条件变量;互斥应该足够了


而且,
已更改的
变量对您没有帮助;它只允许一个线程看到更改。也删除它。

我认为您不需要条件变量;互斥应该足够了


而且,
已更改的
变量对您没有帮助;它只允许一个线程看到更改。也删除它。

实际上,在阅读器中调用
notify_one()
是一种奇怪的方法(
Get
)!如果您想让读者等待某项设置完成,那么您需要以下内容:

 void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
    ++stateCounter;  // some int to track state chages
    myCondvar.notify_all(); // notify all readers
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    // copy the current state
    int cState = stateCounter;
    // waits for a notification and change of state
    while (stateCounter == cState)
      myCondvar.wait( lock );
  }

现在,对
Get
的调用将有效地等待状态的有效更改。然而,这种方法(有条件的)容易出现诸如虚假唤醒(应该由循环处理)、丢失通知等问题。您需要为此找到更好的模型(所有这些听起来都像是每个线程都有一个队列)。

实际上,在读卡器(
Get
)中调用
notify_one()
是一种奇怪的方法!如果您想让读者等待某项设置完成,那么您需要以下内容:

 void Set(int i) 
  {
    boost::mutex::scoped_lock lock(myMutex);
    myData = i; // set the data
    ++stateCounter;  // some int to track state chages
    myCondvar.notify_all(); // notify all readers
  }

  void Get( int& i)
  {
    boost::mutex::scoped_lock lock(myMutex);
    // copy the current state
    int cState = stateCounter;
    // waits for a notification and change of state
    while (stateCounter == cState)
      myCondvar.wait( lock );
  }

现在,对
Get
的调用将有效地等待状态的有效更改。但是,这种方法(有条件)容易出现诸如虚假唤醒(应由循环处理)、丢失通知等问题。您需要找到一个更好的模型(所有大多数听起来都像是每个线程都有一个队列)。

I updated post-您的意思是我发布的更新可以工作吗?我的主要观点是让读者不要在一个集合上阅读超过一次…我想这是可行的(尽管您可能需要将
myData
声明为
volatile
,以防止编译器进行不安全的优化。我不确定您所说的“在每个集合上阅读不超过一次”是什么意思。您肯定只想
get()
每次读线程调用时安全返回最新值?我试图在这里解释我更新了帖子-你的意思是我发布的更新会起作用吗?我的要点是,读者不要在一个集合上阅读超过一次…我想这会起作用(虽然您可能需要将
myData
声明为
volatile
,以防止编译器进行不安全的优化。我不确定您所说的“每次读取不超过一次”是什么意思。您肯定只想
get()
要在每次读卡器线程调用时安全地返回最近的值,我尝试在这里进行解释