C ++终止调用没有一个活动的exception
我得到一个C ++线程错误:
terminate called without an active exception Aborted
这里是代码:
#include <queue> #include <thread> #include <mutex> #include <condition_variable> template<typename TYPE> class blocking_stream { public: blocking_stream(size_t max_buffer_size_) : max_buffer_size(max_buffer_size_) { } //PUSH data into the buffer blocking_stream &operator<<(TYPE &other) { std::unique_lock<std::mutex> mtx_lock(mtx); while(buffer.size()>=max_buffer_size) stop_if_full.wait(mtx_lock); buffer.push(std::move(other)); mtx_lock.unlock(); stop_if_empty.notify_one(); return *this; } //POP data out of the buffer blocking_stream &operator>>(TYPE &other) { std::unique_lock<std::mutex> mtx_lock(mtx); while(buffer.empty()) stop_if_empty.wait(mtx_lock); other.swap(buffer.front()); buffer.pop(); mtx_lock.unlock(); stop_if_full.notify_one(); return *this; } private: size_t max_buffer_size; std::queue<TYPE> buffer; std::mutex mtx; std::condition_variable stop_if_empty, stop_if_full; bool eof; };
我围绕这个例子模拟了我的代码: http : //www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
我在做什么错了,我该如何解决这个错误?
当线程对象超出范围并且处于可连接状态时,程序将被终止。 标准委员会有两个其他选项可用于可连接线程的析构函数。 它可以悄悄地join – 但是如果线程卡住,连接可能永远不会返回。 或者它可以分离线程(分离线程不可连接)。 但是,分离的线程非常棘手,因为它们可能会一直存在,直到程序结束并且弄乱了资源的释放。 所以,如果你不想终止你的程序,确保你join(或分离)每一个线程。
如何重现该错误:
#include <iostream> #include <stdlib.h> #include <string> #include <thread> using namespace std; void task1(std::string msg){ cout << "task1 says: " << msg; } int main() { std::thread t1(task1, "hello"); return 0; }
编译并运行:
el@defiant ~/foo4/39_threading $ g++ -os s.cpp -pthread -std=c++11 el@defiant ~/foo4/39_threading $ ./s terminate called without an active exception Aborted (core dumped)
你得到这个错误,因为你没有join或脱离你的线程。
一种方法来解决它,像这样join线程:
#include <iostream> #include <stdlib.h> #include <string> #include <thread> using namespace std; void task1(std::string msg){ cout << "task1 says: " << msg; } int main() { std::thread t1(task1, "hello"); t1.join(); return 0; }
然后编译并运行:
el@defiant ~/foo4/39_threading $ g++ -os s.cpp -pthread -std=c++11 el@defiant ~/foo4/39_threading $ ./s task1 says: hello
另一种方法来解决它,像这样分离它:
#include <iostream> #include <stdlib.h> #include <string> #include <unistd.h> #include <thread> using namespace std; void task1(std::string msg){ cout << "task1 says: " << msg; } int main() { { std::thread t1(task1, "hello"); t1.detach(); } //thread handle is destroyed here, as goes out of scope! usleep(1000000); //wait so that hello can be printed. }
编译并运行:
el@defiant ~/foo4/39_threading $ g++ -os s.cpp -pthread -std=c++11 el@defiant ~/foo4/39_threading $ ./s task1 says: hello
阅读分离C ++线程并joinC ++线程。
Eric Leschinski和Bartosz Milewski已经给出了答案。 在这里,我会尝试以更加初学友好的方式呈现。
一旦一个线程在一个范围内(它本身正在一个线程上运行)中启动,就必须在线程超出范围之前明确地确保下列情况之一发生:
- 只有在线程完成执行后,运行时才退出范围。 这是通过join该线程来实现的。 注意语言,它是与该线程连接的外部作用域。
- 运行时会使线程自行运行。 所以程序会退出这个范围,不pipe这个线程是否执行完毕。 该线程自行执行并退出。 这是通过分离线程来实现的。 这可能会导致问题,例如,如果线程引用该外部作用域中的variables。
注意,当线程被连接或分离时,它可能已经完成执行。 仍然必须明确地执行这两个操作中的任一个。