it-swarm.it

C ++ termina chiamato senza un'eccezione attiva

Ricevo un errore C++ con il threading:

terminate called without an active exception
Aborted

Ecco il codice:

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

Ho modellato il mio codice attorno a questo esempio: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

Cosa sto facendo di sbagliato e come posso correggere l'errore?

66
111111

Quando un oggetto thread esce dall'ambito ed è nello stato di join, il programma viene terminato. Il Comitato Standard aveva altre due opzioni per il distruttore di un thread unibile. Potrebbe unirsi tranquillamente, ma potrebbe non tornare mai se il thread è bloccato. Oppure potrebbe staccare il thread (un thread separato non è unibile). Tuttavia, i thread separati sono molto complicati, poiché potrebbero sopravvivere fino alla fine del programma e incasinare il rilascio di risorse. Quindi, se non vuoi terminare il tuo programma, assicurati di unirti (o staccare) ogni thread.

92

Come riprodurre quell'errore:

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

Compila ed esegui:

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

Ricevi questo errore perché non hai aderito o rimosso il tuo thread.

n modo per risolverlo, unisciti al thread in questo modo:

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

Quindi compilare ed eseguire:

[email protected] ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
[email protected]ant ~/foo4/39_threading $ ./s
task1 says: hello

L'altro modo per risolverlo, staccalo in questo modo:

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

Compila ed esegui:

[email protected] ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
[email protected] ~/foo4/39_threading $ ./s
task1 says: hello

Leggi come staccare i thread C++ e unire i thread C++.

37
Eric Leschinski

Eric Leschinski e Bartosz Milewski hanno già dato la risposta. Qui, proverò a presentarlo in un modo più amichevole per i principianti.

Una volta che un thread è stato avviato all'interno di un ambito (che a sua volta è in esecuzione su un thread), è necessario garantire esplicitamente una delle seguenti operazioni prima che il thread esca dall'ambito:

  • Il runtime esce dall'ambito, solo dopo che il thread termina l'esecuzione. Ciò si ottiene unendo quel thread. Nota la lingua, è l'ambito esterno che si unisce a quel thread.
  • Il runtime lascia il thread da eseguire da solo. Quindi, il programma uscirà dall'ambito, indipendentemente dal fatto che questo thread sia terminato o meno. Questo thread viene eseguito ed esce da solo. Ciò si ottiene staccando il filo. Ciò potrebbe causare problemi, ad esempio, se il thread fa riferimento a variabili in quell'ambito esterno.

Nota, quando il thread viene unito o staccato, potrebbe essere stato eseguito correttamente. Ancora una delle due operazioni deve essere eseguita in modo esplicito.

16
haripkannan

Finché il programma muore, quindi senza scollegare o unire il thread, si verificherà questo errore. Senza staccare e unire il thread, devi creare un loop infinito dopo aver creato il thread.

int main(){

std::thread t(thread,1);

while(1){}

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

È anche interessante che, dopo aver dormito o fatto un loop, il thread possa essere staccato o unito. Anche in questo modo non si ottiene questo errore.

L'esempio che segue mostra anche che il terzo thread non può fare il suo lavoro prima del dado principale. Ma questo errore non può verificarsi anche, purché si stacchi da qualche parte nel codice. Il terzo thread è inattivo per 8 secondi, ma il main morirà in 5 secondi.

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