Я получаю ошибку 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
Что я делаю не так и как исправить ошибку?
c++
multithreading
deadlock
c++11
111111
источник
источник
join
включаете все свои потоки в свою основную программу?Ответы:
Когда объект потока выходит за пределы области видимости и находится в состоянии присоединения, программа завершается. У Комитета по стандартизации было два других варианта деструктора соединяемого потока. Он может незаметно присоединиться - но соединение может никогда не вернуться, если поток застрял. Или он может отсоединить нить (отделившаяся нить не может быть присоединена). Однако отдельные потоки очень сложны, так как они могут дожить до конца программы и испортить высвобождение ресурсов. Поэтому, если вы не хотите завершать свою программу, убедитесь, что вы присоединяетесь (или отсоединяете) каждый поток.
источник
std::async
? Как присоединиться / отсоединить любой поток, который может быть создан там? Не похоже, что ожидания в результирующем будущем было бы достаточно, потому что это говорит о том, что поток может «потенциально быть из пула потоков», а future wait () на самом деле не подразумевает завершение потока в пуле (и это не в любом случае не имеет смысла для разумных пулов потоков).std::jthread
вызовет.join()
деструктор (когда он выходит за рамки). Что мне лично больше нравится, так как он лучше соответствует RAII.Как воспроизвести эту ошибку:
#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 ++.
источник
Эрик Лещинский и Бартош Милевски уже дали ответ. Здесь я постараюсь представить это в более дружественной форме для начинающих.
После того, как поток был запущен в области видимости (которая сама работает в потоке), необходимо явно гарантировать, что одно из следующих событий произойдет до того, как поток выйдет из области видимости:
Обратите внимание, что к тому времени, когда поток будет присоединен или отсоединен, он может хорошо завершить выполнение. Тем не менее, любая из двух операций должна выполняться явно.
источник
Пока ваша программа умирает, эта ошибка будет возникать без отсоединения или присоединения к потоку. Без отсоединения и присоединения к потоку вы должны создать бесконечный цикл после создания потока.
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;}
источник
год, поток должен быть join (). когда главный выход
источник
Сначала вы определяете поток. И если вы никогда не вызовете join () или detach () перед вызовом деструктора потока, программа прервется.
Таким образом, вызов деструктора потока без предварительного вызова join (чтобы дождаться его завершения) или отсоединения гарантирует немедленный вызов std :: terminate и завершение программы.
источник