c++ - threads - thread was not declared in this scope
Quiero matar un std:: thread usando su objeto thread? (2)
Posible duplicado:
C ++ 0x interrupcion de hilo
Estoy tratando de matar / detener un c ++ std :: thread usando su objeto thread.
¿Cómo podemos hacer esto?
La respuesta de @ bamboon es buena, sin embargo, siento que esto merece una declaración más fuerte.
Independientemente del idioma que utilice, su programa adquirirá y liberará recursos: memoria, descriptores de archivos, ... Para los programas simples que se activan de una vez, las pérdidas de recursos no importan mucho: cuando el programa finaliza, los sistemas operativos modernos recuperan automáticamente los recursos. ; sin embargo, para los programas de larga ejecución, un requisito básico es no perder recursos, o al menos no de manera repetitiva.
Por lo tanto, debería haber aprendido desde el principio que cuando adquiera un recurso tendrá que asegurarse de que se libere en un punto:
void foo(int i) {
int* array = malloc(sizeof(int) * i);
/* do something */
free(array);
}
Entonces, hazte la pregunta:
- ¿Qué pasa cuando mato el programa?
- ¿Qué pasa cuando mato el hilo?
Bueno, como dijimos, cuando un programa finaliza, el sistema operativo recupera los recursos, por lo que suponiendo (y esto es un supuesto) que no adquirió un recurso en otro sistema O que este sistema está bien protegido contra tal abuso, no hay daño, ninguna falta
Sin embargo, cuando se elimina un hilo, el programa aún se ejecuta, por lo que el sistema operativo no recupera los recursos. En tu memoria perdida, bloqueaste un archivo para escribir que no puedes desbloquear por más tiempo ... No debes matar hilos .
Los idiomas de nivel superior tienen una forma de manejar esto: excepciones. Debido a que los programas deberían estar a salvo de las excepciones de todos modos, Java (por ejemplo) eliminará un subproceso haciendo una pausa, lanzando una excepción en el punto de ejecución y desenrollando suavemente la pila. Sin embargo, no existe tal facilidad en C ++, todavía.
¿Es imposible? No, obviamente no. En realidad, podría reutilizar perfectamente la misma idea:
- encapsulate
std::thread
,interruptible_thread
class también contendrá un indicador de interrupción - pase la dirección de la bandera a
std::thread
cuando la inicie, y guárdela de manera local - Instale su código con puntos de verificación donde verifique si el indicador de interrupción está establecido o no, y cuando se produce una excepción.
Es decir:
// Synopsis
class interrupt_thread_exception;
class interruptible_thread;
void check_for_interrupt();
// Interrupt exception
class interrupt_thread_exception: public virtual std::exception {
public:
virtual char const* what() const override { return "interrupt"; }
}; // class interrupt_thread_exception
// Interruptible thread
class interruptible_thread {
public:
friend void check_for_interrupt();
template <typename Function, typename... Args>
interruptible_thread(Function&& fun, Args&&... args):
_thread([](std::atomic_bool& f, Function&& fun, Args&&... args) {
_flag_ref = &f; fun(std::forward<Args>(args)...);
},
_flag,
std::forward<Function>(fun),
std::forward<Args>(args)...)
{}
bool stopping() const { return _flag.load(); }
void stop() { _flag.store(true); }
private:
static thread_local std::atomic_bool* _flag_ref = nullptr;
std::atomic_bool _flag = false;
std::thread _thread;
}; // class interruptible_thread
// Interruption checker
inline void check_for_interrupt() noexcept(false) {
if (not interruptible_thread::_flag_ref) { return; }
if (not interruptible_thread::_flag_ref->load()) { return; }
throw interrupt_thread_exception();
} // check_for_interrupt
Ahora puede simplemente esparcir su código roscado con chequeos de interrupción en los lugares apropiados.
Usted no puede
std::threads
no son interrumpibles. Puedes usar boost::thread
que ofrece esta característica.
Boost hace esto definiendo "puntos de interrupción" en los cuales el hilo terminará si se interrumpe y llega a ese punto.
Sin embargo, la mayoría de las veces, pensar en un rediseño puede ser la forma más limpia y fácil de alcanzar lo que está tratando de lograr.
Si todavía está buscando una implementación en C ++ 11 de la salida de subprocesos interrumpibles, haga clic en el libro de Anthony Williams (propietario del subproceso de refuerzo) "C ++ Concurrencia en Acción". Pasa por una implementación básica de cómo se puede lograr tal cosa.
std::thread::native_handle
le da acceso al controlador de subprocesos subyacente específico de la plataforma que podría permitir la interrupción, sin embargo, este enfoque hace que su código no sea portátil y probablemente no sea más limpio de ninguna manera.