【问题标题】:Proper way to wait for multiple threads to complete before exiting program in c++ 11在c ++ 11中退出程序之前等待多个线程完成的正确方法
【发布时间】:2016-04-02 12:39:35
【问题描述】:

下面的代码示例将有效地允许一次执行一个 1 个线程。保留对线程的引用,然后稍后调用“Thread.join”具有相同的效果。如何让这些线程以这样的方式运行,程序等待线程独立并行继续,然后退出?在我看来,必须使用其他一些内核对象信号机制。 (简而言之,使用 'join' 将主线程绑定到辅助线程不会让其他线程同时运行?)

int main() {
    while (cin) {
        getline(cin, input_line);
        if (input_line.length()>0)
        {
            thread t = thread(SomeLengthyCheck, input_line);
            t.join();
        }
    }
}

【问题讨论】:

  • "简而言之,使用 'join' 将主线程绑定到辅助线程不会让其他线程同时运行?" ——这个假设是完全错误的。只需启动仅休眠一秒钟的多个线程。然后,加入所有这些线程并观察整个程序需要多少时间。
  • @Ulrich 我指的是我上面的代码片段,因为在 while 循环中调用 'thread.join' 的效果甚至不会启动其他线程。在所有线程之后使用连接created 将允许其他线程继续运行直到完成(如下所述)。此外,我理解规范声明即使在主线程退出后线程也应该继续,但我对这种方法不满意......

标签: multithreading c++11


【解决方案1】:

您通常使用线程数组,然后在 for 循环中等待所有这些。

您不必关心订单,因为最终,所有订单都应该完成。

根据您的情况,您需要一个线程堆栈/队列,因为您不知道需要等待多少线程。

int main() {
    std::vector<std::thread> threads;
    std::string input_line;
    while (getline(std::cin, input_line)) {
        if (input_line.length()>0) {
            threads.push_back(std::thread(SomeLengthyCheck, input_line));
        }
    }
    for (auto& th : threads) th.join();    
}

编辑:@o11c 建议的异常安全版本

class vthreads : std::vector<std::thread> {
    ~vthreads() { for (auto& th : *this ) th.join(); }
};

int main() {
    vthreads threads;
    std::string input_line;
    while (getline(std::cin, input_line)) {
        if (input_line.length()>0) {
            threads.push_back(std::thread(SomeLengthyCheck, input_line));
        }
    }
}

【讨论】:

  • 这不是异常安全的。最好将调用 .join 放在一个会自动调用的析构函数中。
  • @o11c 很好,将其添加到答案中。
【解决方案2】:

我不是 linux 专家,但我认为线程附加到 main 的进程,所以当任何线程异步操作主线程时,只需 return-ing 在 main 中就会有操作系统。关闭进程并附加所有子线程。

否则我相信当调用函数在封闭{}之后完成时线程将结束

当全局变量发生这种情况时,您可以向主进程发出信号。

我也认为你对加入感到困惑。 Join 强制异步线程(函数)基本上同步运行,方法是停止调用线程,直到要加入的线程完成。

【讨论】:

  • 全局变量应该可以工作,因为父进程的线程共享相同的内存资源。
  • 该行为不是由 Linux 定义的,而是由 C++ 标准定义的。该标准还规定std::thread 必须在其析构函数调用之前分离或加入。我认为,只需离开创建std::thread 的范围,两者都不会,导致调用abort()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
相关资源
最近更新 更多