Подтвердить что ты не робот

С++ завершение вызова без активного исключения

Я получаю С++-ошибку с threading:

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

Что я делаю неправильно и как исправить ошибку?

4b9b3361

Ответ 1

Когда объект потока выходит из области действия и он находится в состоянии соединения, программа завершается. У стандартного комитета были два других варианта деструктора сплошной нити. Он может спокойно присоединиться, но соединение никогда не вернется, если поток застрял. Или он может отсоединить нить (отсоединенная резьба не соединяется). Однако отдельные потоки очень сложны, так как они могут выжить до конца программы и испортить выпуск ресурсов. Поэтому, если вы не хотите прекращать свою программу, убедитесь, что вы присоединяете (или отсоединяете) каждый поток.

Ответ 2

Как воспроизвести эту ошибку:

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

Скомпилировать и запустить:

[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)

Вы получаете эту ошибку, потому что не присоединились или не отсоединили свой поток.

Один из способов исправить это, присоедините поток следующим образом:

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

Затем скомпилируйте и запустите:

[email protected] ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11
[email protected] ~/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.
}

Скомпилировать и запустить:

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

Читайте об отсоединении потоков С++ и подключении потоков С++.

Ответ 3

Эрик Лещинский и Бартош Милевский уже дали ответ. Здесь я попытаюсь представить его более дружелюбным образом.

Как только поток запущен в пределах области (которая сама запускается в потоке), необходимо явно убедиться, что одно из следующего происходит до того, как поток выходит из области видимости:

  • Время выполнения выходит из области действия, только после того, как этот поток завершит выполнение. Это достигается путем соединения с этим потоком. Обратите внимание на язык, это внешняя область, которая соединяется с этим потоком.
  • Среда выполнения оставляет поток для запуска самостоятельно. Таким образом, программа выйдет из области, независимо от того, закончил ли этот поток выполнение или нет. Этот поток выполняется и выходит сам по себе. Это достигается путем отсоединения резьбы. Это может привести к проблемам, например, если поток ссылается на переменные в этой внешней области.

Обратите внимание, что к моменту присоединения потока или отсоединения он может быть хорошо закончен. Тем не менее любая из двух операций должна выполняться явно.

Ответ 4

Пока ваша программа умирает, то без отсоединения или присоединения потока эта ошибка будет возникать. Не отсоединяя и не присоединяя поток, вы должны создать бесконечный цикл после создания потока.

int main(){

std::thread t(thread,1);

while(1){}

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

Также интересно, что после сна или зацикливания нить может быть отсоединена или присоединена. Также с этим способом вы не получите эту ошибку.

Приведенный ниже пример также показывает, что третий поток не может выполнить свою работу до основного кубика. Но эта ошибка также не может произойти, пока вы отсоединяетесь где-то в коде. Третий поток спит 8 секунд, но основной умрет через 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;}

Ответ 5

год, поток должен быть join(). когда главный выход