加入线程时出现异常

时间:2016-06-17 23:27:45

标签: c++ multithreading g++

以下测试程序使用g++ -o test -pthread -std=c++11 test.cpp进行编译就好了:

#include <iostream>
#include <vector>
#include <thread>
#include <chrono>

using namespace std;

void foo(int);

int main()
{
        vector<thread> threads(5);
        for (int i = 0; i < 5; i++)
        {
                threads.push_back(thread(foo, i));
        }

        for (vector<thread>::iterator iter = threads.begin(); iter != threads.end(); iter++)
        {
                iter->join();
        }
}

void foo(int id)
{
        cout << "thread " << id << " started.";
        this_thread::sleep_for(chrono::seconds(10));
        cout << "thread " << id << " terminated.";
}

但是,在运行时,它会提供与此类似的输出:

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument
thread thread 2 started.1 started.thread 4 started.thread 3 started.thread 0 started.Aborted (core dumped)  

我不知道这个错误来自哪里。从调试开始,我知道一旦我尝试加入第一个线程就会发生错误 http://www.cplusplus.com/reference/thread/thread/join/表示如果线程不可连接,则join只会抛出invalid_argument http://www.cplusplus.com/reference/thread/thread/joinable/表示只有在以下情况下线程才可以连接:

  • 它是默认构造的。
  • 它已被移动(构造另一个线程对象或分配给它)。
  • 已调用其成员加入或分离。

正如人们可以清楚地看到的那样,该线程并非默认构造 我永远不会用另一个线程对象覆盖该线程。程序的输出还显示每个线程都在运行,因为“线程x已启动”。达成了陈述 我只为每个线程调用一次join。

如果我在创作和加入之间暂停5秒钟,我会得到同样的结果,所以这不是种族问题。虽然有趣的是输出仍然以相同的方式排序。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

您不应该使用5个默认构造的线程来预设vector,然后在push_back处理其他线程时忽略这些线程。然后你的join尝试加入默认构造的线程并抛出。摆脱(5),或将其移至reserve来电。