c++ - 如何避免在 C++ 中进行一些繁重的处理时阻塞线程?

标签 c++ multithreading c++11 thread-safety pthreads

我是 C++ 多线程程序的初学者。我为我的问题创建了一个虚拟代码。 Hoge 类是连接套接字的通信类,我假设 Hoge::update() 是通过套接字接收数据的类。如果特定数据到达,Hoge 实例将数据传递给 Fuga 实例进行特定处理。

所以我的问题是,

  1. 我不想阻止 Hoge::update()。所以存储数据后,我不想使用th_process_data.join()。对此有更好的解决方案吗?
  2. 在另一个线程中处理数据后,如何将处理后的数据返回给Hoge实例。一些回调类是解决方案?

Hoge.cc

Fuga fuga;
Hoge::update() {
  while(true) {
    if(check_something()) {
      auto data = get_data();
      fuga.push_data(data);
    }
  }
}

Hoge::on_received(const Data& data) {
  std::cout << "received: " << data.id << std::endl;
  // do something...
}

风雅网

std::vector<Data> data_list;
std::mutex mtx;

Fuga::push_data(const Data& data) {
  {
    std::lock_guard<std::mutex> lock(mtx);
    data_list.push_back(data);
  }
  std::thread th_process_data([&]{ do_processing(); });
  // Q1. I don't want to block this thread for Hoge::update()
}

Fuga::do_processing() {
  Data data;
  {
    std::lock_guard<std::mutex> lock(mtx);
    data = data_list.pop();
  }

  // heavy task for data...
  std::this_thread::sleep_for(std::chrono::seconds(3)); 

  // Q2. How to pass this processed data to Hoge::on_received(const Data& data)
}

最佳答案

您的部分问题对我来说不是很清楚,因为它似乎有很多可能性。但是,您的 2 个查询是客观的,因此我试图根据我最近使用套接字的经验来回答。

"1. I don't want to block Hoge::update(). So after storing data, I don't want to use th_process_data.join(). Are there any better solution for this?"

在这种情况下,您可以:

th_process_data.detach();

这将使您免于阻塞 .join()。如果您的设计允许,您也可以使用 std::futurestd::promise 组合。更多信息可以在 this post 中找到.

"2. After processing data in another thread, how to return this processed data to Hoge instance. Some callback class is solution?"

我认为简单地调用 Hoge::on_received() 方法并传递 data 没什么大不了的。该线程仍然只是th_process_data。如果您担心为它提供时间切片和使用 sleep_for() 方法,那么您也可以寻找 std::yield 作为替代方案。


根据您当前的设计,您已将 2 个 std::mutex 放入 2 个方法中。我觉得,这不是必需的。
另外,请记住,每次调用 Fuga::push_data() 时,您都会创建一个 thread。如果频繁调用此方法并且您不想以创建多线程为代价来加载 CPU,那么最好创建一次单线程并在其中等待接收数据。但这将需要更改设计。

关于c++ - 如何避免在 C++ 中进行一些繁重的处理时阻塞线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37670320/

相关文章:

multithreading - performSelectorOnMainThread 与 performSegue

c++ - 允许 const 成员函数使用 mutable 编辑一些成员变量

c++ - 线程 vector 中的假缓存共享 C++

c++ - 如何链接到 C++ 中的共享库

java - Netty 4 从客户端创建多个连接

c++ - 通过 SHM 的 IPC 用于 C++ 和并发内存访问

c++ - 了解 Windows 中代码块的 g++ 版本

c++ - 防止返回的引用被复制

c++ - 在任何操作系统上,C/C++ 中的 int main() 返回 0 是否会清除程序在任何(RAM、高速缓存或任何...)内存中使用的所有资源?

c++ - 使用自定义比较器声明 C++ 优先级队列的问题