C++在没有活动异常的情况下终止调用

发布于 2024-12-03 19:26:45 字数 1665 浏览 0 评论 0原文

我在线程处理方面遇到 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

我做错了什么以及如何修复错误?

I am getting a C++ error with threading:

terminate called without an active exception
Aborted

Here is the code:

#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;   
};

I modeled my code around this example:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

What am I doing wrong and how do I fix the error?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

破晓 2024-12-10 19:26:45

当线程对象超出范围并且处于可连接状态时(即 - 假设线程对象名为 tt.joinable() 返回 true),程序被终止。标准委员会对于可连接线程的析构函数还有另外两个选择。它可以悄悄地加入——但如果线程被卡住,加入可能永远不会返回。或者它可以分离线程(分离的线程不可连接)。然而,分离线程非常棘手,因为它们可能会一直存在到程序结束并扰乱资源的释放。因此,如果您不想终止程序,请确保加入(或分离)每个线程。

When a thread object goes out of scope and it is in joinable state (i.e. - assuming the thread object is named t then t.joinable() returns true), the program is terminated. The Standard Committee had two other options for the destructor of a joinable thread. It could quietly join -- but join might never return if the thread is stuck. Or it could detach the thread (a detached thread is not joinable). However, detached threads are very tricky, since they might survive till the end of the program and mess up the release of resources. So if you don't want to terminate your program, make sure you join (or detach) every thread.

泪之魂 2024-12-10 19:26:45

如何重现该错误:

#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++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
terminate called without an active exception
Aborted (core dumped)

您会收到该错误,因为您没有加入或分离线程。

修复它的一种方法,像这样加入线程:

#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++ -o s 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++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
task1 says: hello

阅读分离 C++ 线程和加入 C++ 线程。

How to reproduce that error:

#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;
}

Compile and run:

el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
terminate called without an active exception
Aborted (core dumped)

You get that error because you didn't join or detach your thread.

One way to fix it, join the thread like this:

#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;
}

Then compile and run:

el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
task1 says: hello

The other way to fix it, detach it like this:

#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.
}

Compile and run:

el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
el@defiant ~/foo4/39_threading $ ./s
task1 says: hello

Read up on detaching C++ threads and joining C++ threads.

彼岸花似海 2024-12-10 19:26:45

Eric Leschinski 和 Bartosz Milewski 已经给出了答案。在这里,我将尝试以更适合初学者的方式来介绍它。

一旦线程在某个范围内启动(该线程本身在线程上运行),就必须显式确保在线程超出范围之前发生以下情况之一:

  • 仅在该线程完成执行后,运行时才退出该范围。这是通过加入该线程来实现的。请注意语言,它是与该线程连接的外部范围。
  • 运行时让线程自行运行。因此,无论该线程是否执行完毕,程序都会退出作用域。该线程自行执行并退出。这是通过分离线程来实现的。例如,如果线程引用该外部作用域中的变量,这可能会导致问题。

请注意,当线程加入或分离时,它可能已经完成执行。仍然必须显式执行这两个操作中的任何一个。

Eric Leschinski and Bartosz Milewski have given the answer already. Here, I will try to present it in a more beginner friendly manner.

Once a thread has been started within a scope (which itself is running on a thread), one must explicitly ensure one of the following happens before the thread goes out of scope:

  • The runtime exits the scope, only after that thread finishes executing. This is achieved by joining with that thread. Note the language, it is the outer scope that joins with that thread.
  • The runtime leaves the thread to run on its own. So, the program will exit the scope, whether this thread finished executing or not. This thread executes and exits by itself. This is achieved by detaching the thread. This could lead to issues, for example, if the thread refers to variables in that outer scope.

Note, by the time the thread is joined with or detached, it may have well finished executing. Still either of the two operations must be performed explicitly.

风吹雨成花 2024-12-10 19:26:45

首先定义一个线程。如果在调用线程析构函数之前从未调用 join() 或 detach(),程序将中止。

如下所示,调用线程析构函数而不首先调用 join (等待其完成)或 detach 可以保证立即调用 std::terminate 并结束程序。

隐式分离或加入 joinable() 线程
析构函数可能会导致难以调试正确性(对于分离)
或仅在异常发生时遇到的性能(对于连接)错误
提出。因此,程序员必须确保析构函数永远不会
当线程仍然可连接时执行。

First you define a thread. And if you never call join() or detach() before calling the thread destructor, the program will abort.

As follows, calling a thread destructor without first calling join (to wait for it to finish) or detach is guarenteed to immediately call std::terminate and end the program.

Either implicitly detaching or joining a joinable() thread in its
destructor could result in difficult to debug correctness (for detach)
or performance (for join) bugs encountered only when an exception is
raised. Thus the programmer must ensure that the destructor is never
executed while the thread is still joinable.

如果没有 2024-12-10 19:26:45

是的,线程必须是join()。当主出口

yes, the thread must be join(). when the main exit

镜花水月 2024-12-10 19:26:45

只要你的程序死了,然后没有分离或加入线程,就会发生这个错误。在不分离和加入线程的情况下,创建线程后应该进行无限循环。

int main(){

std::thread t(thread,1);

while(1){}

//t.detach();
return 0;}

同样有趣的是,在睡眠或循环之后,线程可以分离或连接。另外,通过这种方式,您不会收到此错误。

下面的示例还表明,第三个线程无法在主线程死亡之前完成其工作。但只要您在代码中的某个位置分离,这个错误也不会发生。
第三个线程休眠 8 秒,但 main 将在 5 秒后死亡。

void thread(int n) {std::this_thread::sleep_for (std::chrono::seconds(n));}

int main() {
std::cout << "Start main\n";
std::thread t(thread,1);
std::thread t2(thread,3);
std::thread t3(thread,8);
sleep(5);

t.detach();
t2.detach();
t3.detach();
return 0;}

As long as your program die, then without detach or join of the thread, this error will occur. Without detaching and joining the thread, you should give endless loop after creating thread.

int main(){

std::thread t(thread,1);

while(1){}

//t.detach();
return 0;}

It is also interesting that, after sleeping or looping, thread can be detach or join. Also with this way you do not get this error.

Below example also shows that, third thread can not done his job before main die. But this error can not happen also, as long as you detach somewhere in the code.
Third thread sleep for 8 seconds but main will die in 5 seconds.

void thread(int n) {std::this_thread::sleep_for (std::chrono::seconds(n));}

int main() {
std::cout << "Start main\n";
std::thread t(thread,1);
std::thread t2(thread,3);
std::thread t3(thread,8);
sleep(5);

t.detach();
t2.detach();
t3.detach();
return 0;}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文