Recibo un error de C ++ con subprocesos:
terminate called without an active exception
Aborted
Aquí está el código:
#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;
};
Modelé mi código en torno a este ejemplo: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
¿Qué estoy haciendo mal y cómo soluciono el error?
c++
multithreading
deadlock
c++11
111111
fuente
fuente
join
todos sus hilos en su programa principal?Respuestas:
Cuando un objeto de subproceso sale del alcance y está en estado unible, el programa finaliza. El Comité de Estándares tenía otras dos opciones para el destructor de un hilo unible. Podría unirse silenciosamente, pero es posible que la unión nunca regrese si el hilo está atascado. O podría separar el hilo (un hilo separado no se puede unir). Sin embargo, los hilos separados son muy complicados, ya que pueden sobrevivir hasta el final del programa y estropear la liberación de recursos. Entonces, si no desea terminar su programa, asegúrese de unirse (o desconectar) cada hilo.
fuente
std::async
? ¿Cómo se une / separa cualquier hilo que pueda crearse allí? No parece que esperar en el futuro resultante sea suficiente, porque esto dice que el hilo podría "potencialmente ser de un grupo de hilos", y el futuro wait () no implica realmente terminar un hilo en un grupo (y eso no sería no tiene sentido de todos modos para grupos de hilos cuerdos).std::jthread
llamará.join()
al destructor (ya que sale del alcance). Lo que personalmente me gusta más ya que sigue mejor a RAII.Cómo reproducir ese 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; }
Compila y ejecuta:
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)
Obtienes ese error porque no te uniste o desconectaste tu hilo.
Una forma de solucionarlo, únete al hilo de esta manera:
#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; }
Luego compila y ejecuta:
el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11 el@defiant ~/foo4/39_threading $ ./s task1 says: hello
La otra forma de solucionarlo, sepárelo así:
#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 y ejecuta:
el@defiant ~/foo4/39_threading $ g++ -o s s.cpp -pthread -std=c++11 el@defiant ~/foo4/39_threading $ ./s task1 says: hello
Obtenga más información sobre cómo separar subprocesos de C ++ y unirse a subprocesos de C ++.
fuente
Eric Leschinski y Bartosz Milewski ya han dado la respuesta. Aquí, intentaré presentarlo de una manera más amigable para principiantes.
Una vez que se ha iniciado un hilo dentro de un alcance (que a su vez se está ejecutando en un hilo), uno debe asegurarse explícitamente de que ocurra una de las siguientes situaciones antes de que el hilo salga del alcance:
Tenga en cuenta que para cuando el hilo se une o se separa, es posible que haya terminado de ejecutarse. Aún así, cualquiera de las dos operaciones debe realizarse explícitamente.
fuente
Mientras su programa muera, entonces sin separarse o unirse al hilo, se producirá este error. Sin separar y unir el hilo, debe dar un bucle sin fin después de crear el hilo.
int main(){ std::thread t(thread,1); while(1){} //t.detach(); return 0;}
También es interesante que, después de dormir o enrollar, el hilo se puede separar o unir. Además, de esta forma no obtendrá este error.
El siguiente ejemplo también muestra que el tercer hilo no puede hacer su trabajo antes del troquel principal. Pero este error no puede ocurrir también, siempre que se separe en algún lugar del código. El tercer hilo duerme durante 8 segundos, pero el principal morirá en 5 segundos.
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;}
fuente
año, el hilo debe ser join (). cuando la salida principal
fuente
Primero define un hilo. Y si nunca llama a join () o detach () antes de llamar al destructor del hilo, el programa abortará.
De la siguiente manera, se garantiza que llamar a un destructor de subprocesos sin llamar primero a join (para esperar a que finalice) o detach para llamar inmediatamente a std :: terminate y finalizar el programa.
fuente