tutorial threads thread not libreria ejemplo declared algorithms c++ multithreading c++11

c++ - threads - thread was not declared in this scope



¿Cómo termino un hilo en C++ 11? (4)

  1. Puedes llamar a std::terminate() desde cualquier hilo y el hilo al que te refieres terminará con fuerza.

  2. Puede organizar que ~thread() se ejecute en el objeto de la secuencia de destino, sin una join() intermedia join() ni detach() en ese objeto. Esto tendrá el mismo efecto que la opción 1.

  3. Puede diseñar una excepción que tenga un destructor que arroje una excepción. Y luego haga los arreglos para que el hilo objetivo arroje esta excepción cuando se termine a la fuerza. La parte difícil de este es obtener el hilo objetivo para lanzar esta excepción.

Las opciones 1 y 2 no filtran recursos dentro del proceso, pero terminan cada hilo.

La opción 3 probablemente perderá recursos, pero es parcialmente cooperativa en el sentido de que el hilo objetivo debe aceptar lanzar la excepción.

No existe una forma portátil en C ++ 11 (que yo sepa) de matar de forma no cooperativa un único hilo en un programa de múltiples hilos (es decir, sin matar a todos los hilos). No hubo motivación para diseñar tal característica.

Un std::thread puede tener esta función miembro:

native_handle_type native_handle();

Es posible que pueda usar esto para llamar a una función dependiente del sistema operativo para hacer lo que desee. Por ejemplo, en el sistema operativo de Apple, esta función existe y native_handle_type es un pthread_t . Si tiene éxito, es probable que pierda recursos.

No es necesario que termine el hilo correctamente o que responda a un comando de "finalización". Estoy interesado en terminar el hilo con fuerza usando C ++ 11 puro.


Consejos para utilizar la función dependiente del sistema operativo para finalizar el hilo de C ++:

  1. std::thread::native_handle() solo puede obtener el tipo de identificador nativo válido del subproceso antes de llamar a join() o detach() . Después de eso, native_handle() devuelve 0 - pthread_cancel() generará un coredump.

  2. Para llamar eficazmente a la función de terminación de subproceso nativa (por ejemplo, pthread_cancel) , debe guardar el manejador nativo antes de llamar a std::thread::join() o std::thread::detach() . De modo que su terminador nativo siempre tenga un identificador nativo válido para usar.

Más explicaciones, consulte: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread .


Esta pregunta en realidad tiene una naturaleza más profunda y una buena comprensión de los conceptos de subprocesamiento múltiple en general le proporcionará información sobre este tema. De hecho, no existe ningún lenguaje o sistema operativo que le brinde facilidades para la terminación de subprocesos asíncrona abruptamente sin advertencia de no usarlos. Y todos estos entornos de ejecución recomiendan decididamente al desarrollador o incluso requieren la creación de aplicaciones de subprocesamiento múltiple en la base de la terminación cooperativa o síncrona del subproceso. El motivo de estas decisiones y consejos comunes es que todos están construidos sobre la base del mismo modelo general multihilo.

Comparemos los conceptos de multiprocesamiento y multihilo para comprender mejor las ventajas y limitaciones del segundo.

El multiprocesamiento supone la división de todo el entorno de ejecución en un conjunto de procesos completamente aislados controlados por el sistema operativo. El proceso incorpora y aísla el estado del entorno de ejecución, incluida la memoria local del proceso y los datos que contiene y todos los recursos del sistema, como archivos, conectores y objetos de sincronización. El aislamiento es una característica críticamente importante del proceso, ya que limita la propagación de fallas por los bordes del proceso. En otras palabras, ningún proceso puede afectar la consistencia de cualquier otro proceso en el sistema. Lo mismo es cierto para el comportamiento del proceso, pero en la forma menos restringida y más borrosa. En dicho entorno, cualquier proceso puede ser asesinado en cualquier momento "arbitrario", porque en primer lugar, cada proceso está aislado, en segundo lugar, el sistema operativo tiene conocimientos completos sobre todos los recursos utilizados por el proceso y puede liberarlos sin fugas, y finalmente el proceso será asesinado por SO no realmente en un momento arbitrario, sino en el número de puntos bien definidos donde el estado del proceso es bien conocido.

Por el contrario, multihilo asume la ejecución de múltiples hilos en el mismo proceso. Pero todos estos hilos comparten el mismo cuadro de aislamiento y no hay ningún control del sistema operativo del estado interno del proceso. Como resultado, cualquier subproceso puede cambiar el estado del proceso global y también dañarlo. Al mismo tiempo, los puntos en los que el estado del hilo es conocido como seguro para matar un hilo depende completamente de la lógica de la aplicación y no se conocen ni para el sistema operativo ni para el tiempo de ejecución del lenguaje de programación. Como resultado, la terminación de hilo en el momento arbitrario significa matarlo en un punto arbitrario de su ruta de ejecución y puede conducir fácilmente a la corrupción de datos de todo el proceso, a la memoria y a la fuga de flujos, fugas de hilos y spinlocks y otras primitivas de sincronización dentro del proceso. estado cerrado que impide que otros hilos avancen.

Debido a esto, el enfoque común es forzar a los desarrolladores a implementar la terminación de subprocesos sincrónica o cooperativa, donde un subproceso puede solicitar otra terminación de subproceso y otro subproceso en un punto bien definido puede controlar esta solicitud e iniciar el procedimiento de apagado desde el estado bien definido con la liberación de todos los recursos globales del sistema y los recursos locales de todo el proceso de forma segura y consistente.


La respuesta de @Howard Hinnant es correcta y completa. Pero podría malinterpretarse si se lee demasiado rápido, porque std::terminate() (proceso completo) tiene el mismo nombre que la "terminación" que @AlexanderVX tenía en mente (1 hilo).

Resumen: "terminar 1 hilo + con fuerza (el hilo objetivo no coopera) + C ++ puro 11 = De ninguna manera".