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++;-线程间共享数据_C++_Multithreading_C++11_Data Sharing - Fatal编程技术网

C++ c++;-线程间共享数据

C++ c++;-线程间共享数据,c++,multithreading,c++11,data-sharing,C++,Multithreading,C++11,Data Sharing,我正在编写一个Windows10应用程序,它通过串口从4个不同的传感器(编码器和IMU)收集数据。我在visualstudio中用c++11编写这篇文章。我每个传感器有一个线程,在无限循环中不断地从中提取数据 由于我是新手,我目前正努力以某种方式在单个线程中“收集”数据。我发现我可以使用条件变量向另一个线程发送信号(在我的例子中,我假设当每个传感器完成时,我将向主线程发送信号)。在这种情况下,我是否必须将数据存储在全局变量中,并在写入(从传感器线程)和读取(在主循环中)时使用互斥锁对其进行保护

我正在编写一个Windows10应用程序,它通过串口从4个不同的传感器(编码器和IMU)收集数据。我在visualstudio中用c++11编写这篇文章。我每个传感器有一个线程,在无限循环中不断地从中提取数据

由于我是新手,我目前正努力以某种方式在单个线程中“收集”数据。我发现我可以使用条件变量向另一个线程发送信号(在我的例子中,我假设当每个传感器完成时,我将向主线程发送信号)。在这种情况下,我是否必须将数据存储在全局变量中,并在写入(从传感器线程)和读取(在主循环中)时使用互斥锁对其进行保护

但是,我担心这个过程对于我的应用程序来说可能太慢(每个传感器每1-2毫秒获得一次新数据),因此在主线程读取时锁定数据的过程中,我会丢失一些数据。(在每个传感器线程内)将数据存储在一个局部变量中,然后将该变量复制到一个全局变量中,并且让主线程只从第二个变量读取数据,这有意义吗


如果这些问题很愚蠢,我很抱歉,但我真的需要帮助。任何示例代码都将不胜感激

我将通过使用库在每个传感器上设置异步读取来处理此问题。异步读取完成后,它调用读取处理程序来解析数据,然后设置另一个异步读取。所有读取处理程序都在同一个线程中运行,这使生活变得更加简单。

这看起来就像我要实现的一样。我真的怀疑,如果输入之间有毫秒的间隔(这是一个巨大的时间),那么吞吐量会有问题

如果有人在下面发现任何细微的错误,请告诉我

#include <thread>
#include <iostream>
#include <chrono>
#include <queue>
#include <mutex>
#include <vector>
#include <condition_variable>

using namespace std::chrono_literals;
using std::vector;
using std::thread;
using std::unique_lock;
using std::mutex;
using std::condition_variable;
using std::queue;

class WorkQueue
{
  condition_variable work_available;
  mutex work_mutex;
  queue<int> work;

public:
  void push_work(int item)
  {
    unique_lock<mutex> lock(work_mutex);

    bool was_empty = work.empty();
    work.push(item);

    lock.unlock();

    if (was_empty)
    {
      work_available.notify_one();
    }    
  }

  int wait_and_pop()
  {
    unique_lock<mutex> lock(work_mutex);
    while (work.empty())
    {
      work_available.wait(lock);
    }

    int tmp = work.front();
    work.pop();
    return tmp;
  }
};

int main() {
  WorkQueue work_queue;

  auto producer = [&]() {
    while (true) {
      work_queue.push_work(10);
      std::this_thread::sleep_for(2ms);
    }
  };

  vector<thread> producers;
  producers.push_back(std::thread(producer));
  producers.push_back(std::thread(producer));
  producers.push_back(std::thread(producer));
  producers.push_back(std::thread(producer));

  std::thread consumer([&]() {        
    while (true)
    {
      int work_to_do = work_queue.wait_and_pop();
      std::cout << "Got some work: " << work_to_do << std::endl;
    }
  });

  std::for_each(producers.begin(), producers.end(), [](thread &p) {
    p.join();
  });    

  consumer.join();  
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std::chrono_文本;
使用std::vector;
使用std::线程;
使用std::unique_锁;
使用std::mutex;
使用std::condition_变量;
使用std::queue;
类工作队列
{
条件变量工作可用;
互斥工作;
排队工作;
公众:
无效推送工作(整数项)
{
唯一的锁(工作互斥);
bool was_empty=work.empty();
工作。推(项);
lock.unlock();
如果(是空的)
{
工作可用。通知一个();
}    
}
int wait_和_pop()
{
唯一的锁(工作互斥);
while(work.empty())
{
工作可用。等待(锁定);
}
int tmp=work.front();
work.pop();
返回tmp;
}
};
int main(){
工作队列工作队列;
汽车生产者=[&](){
while(true){
工作队列。推送工作(10);
std::this_线程::sleep_for(2ms);
}
};
媒介生产者;
producers.push_back(std::thread(producer));
producers.push_back(std::thread(producer));
producers.push_back(std::thread(producer));
producers.push_back(std::thread(producer));
std::线程使用者([&](){
while(true)
{
int work_to_do=work_queue.wait_and_pop();

所以,每秒少于5000个数据,如果数据不是很大的话,锁就不会成为问题。但是,将数据异步到主线程可能是一种更清晰的方法。