Nice programing

활성 예외없이 호출 된 C ++ 종료

nicepro 2020. 11. 10. 22:13
반응형

활성 예외없이 호출 된 C ++ 종료


스레딩에서 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

내가 뭘 잘못하고 있고 어떻게 오류를 수정합니까?


스레드 개체가 범위를 벗어나 결합 가능한 상태가되면 프로그램이 종료됩니다. 표준위원회에는 조인 가능한 스레드의 소멸자에 대한 두 가지 다른 옵션이 있습니다. 조용히 조인 할 수 있지만 스레드가 멈춘 경우 조인이 반환되지 않을 수 있습니다. 또는 스레드를 분리 할 수 ​​있습니다 (분리 된 스레드는 결합 할 수 없음). 그러나 분리 된 스레드는 프로그램이 끝날 때까지 살아남아 리소스 해제를 망칠 수 있기 때문에 매우 까다 롭습니다. 따라서 프로그램을 종료하지 않으려면 모든 스레드를 조인 (또는 분리)해야합니다.


오류를 재현하는 방법 :

#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 ++ 스레드 결합에 대해 읽어보십시오.


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.


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

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

참고URL : https://stackoverflow.com/questions/7381757/c-terminate-called-without-an-active-exception

반응형