Multithreading C++;11连接完成的第一个螺纹

Multithreading C++;11连接完成的第一个螺纹,multithreading,c++11,Multithreading,C++11,有没有一种方法可以启动两个(或更多)C++11线程并连接()第一个完成的线程 一个示例场景: #include <iostream> #include <thread> using namespace std; void prepare_item1() {std::cout << "Preparing 1" << std::endl;} void consume_item1() {std::cout << "Consu

有没有一种方法可以启动两个(或更多)C++11线程并连接()第一个完成的线程

一个示例场景:

#include <iostream>
#include <thread>

using namespace std;    
void prepare_item1() {std::cout << "Preparing 1" << std::endl;}    
void consume_item1() {std::cout << "Consuming 1" << std::endl;}    
void prepare_item2() {std::cout << "Preparing 2" << std::endl;}    
void consume_item2() {std::cout << "Consuming 2" << std::endl;}

int main()
{
    std::thread t1(prepare_item1);
    std::thread t2(prepare_item2);

    t1.join();
    consume_item1();

    t2.join();
    consume_item2();

    return 0;
}
另外,我希望解决方案是阻塞的,类似于t.join()函数

注意:我需要它的真正原因是我有两个不同的阻塞函数,我从中接收命令,每当它们中的任何一个就绪时,我都希望处理到达的第一个命令,并在完成后继续处理下一个命令。(来自两个并行源的命令的顺序处理)


谢谢

这是一个线程安全的多生产者多消费者队列:

template<class T>
struct safe_queue {
  std::deque<T> data;
  std::atomic<bool> abort_flag = false;
  std::mutex guard;
  std::condition_variable signal;

  template<class...Args>
  void send( Args&&...args ) {
    {
      std::unique_lock<std::mutex> l(guard);
      data.emplace_back(std::forward<Args>(args)...);
    }
    signal.notify_one();
  }
  void abort() {
    abort_flag = true;   // 1a
    { std::unique_lock<std::mutex>{guard}; }
    signal.notify_all(); // 1b
  }        
  std::experimental::optional<T> get() {
    std::unique_lock<std::mutex> l(guard);
    signal.wait( l, [this]()->bool{ // 2b
      return !data.empty() || abort_flag.load(); // 2c
    });
    if (abort_flag.load()) return {};
    T retval = std::move(data.front());
    data.pop_front();
    return retval;
  }
};
模板
结构安全队列{
std::deque数据;
std::原子中止标志=false;
互斥保护;
std::条件变量信号;
模板
无效发送(Args&&…Args){
{
std::唯一锁l(防护);
data.emplace_back(std::forward)。注意,我认为另一个答案中有一些错误,我在上面更正了这些错误,并尝试解决另一个问题


您发送的消息可能是准备等待的线程的id,例如,或它已完成的工作,或其他任何内容。

我最初会说不,但我确信如果您注册中断,您可能能够以这种特定的方式执行。您需要的是
std::condition\u变量
进一步解释,
std::condition_变量
将在所有线程之间共享。主线程(您阻塞的线程)将由任何线程(t1或t2)发出信号C++调用线程模型是基于POSIX线程模型中的一个最丑陋的东西,C++线程模型是基于一个调用中不能连接多个线程的。MZHm,你的操作系统是什么?如果你在Windows上,你可以简单地使用<代码> WaistFrimeType对象< /C>。在stem中,您必须努力开发自己的线程完成信号机制-例如,通过使用线程id数组和条件变量来等待。每个线程都将使用其id更新向量,并在退出之前发出变量信号。这很麻烦,如果线程崩溃,将不会被注册。但是我没有别的了。
template<class T>
struct safe_queue {
  std::deque<T> data;
  std::atomic<bool> abort_flag = false;
  std::mutex guard;
  std::condition_variable signal;

  template<class...Args>
  void send( Args&&...args ) {
    {
      std::unique_lock<std::mutex> l(guard);
      data.emplace_back(std::forward<Args>(args)...);
    }
    signal.notify_one();
  }
  void abort() {
    abort_flag = true;   // 1a
    { std::unique_lock<std::mutex>{guard}; }
    signal.notify_all(); // 1b
  }        
  std::experimental::optional<T> get() {
    std::unique_lock<std::mutex> l(guard);
    signal.wait( l, [this]()->bool{ // 2b
      return !data.empty() || abort_flag.load(); // 2c
    });
    if (abort_flag.load()) return {};
    T retval = std::move(data.front());
    data.pop_front();
    return retval;
  }
};