Pregunta

programa de MT estoy escribiendo para Linux en C ++ y quiero saber cómo se realiza la cancelación hilo.

Por lo que yo entiendo cuando el hilo se cancela funciones de limpieza se llaman dentro de la función del hilo y la función del hilo se ve obligado a salir. Este significar dos cosas:

  1. Cuando el hilo se cancela todavía llama a los destructores fo todos los objetos de C ++ creado dentro de la función del hilo.
  2. Me puede pasar a funciones de limpieza punteros a objetos creados en función del hilo.

Estoy en lo cierto y el código de abajo el trabajo enfermo de bien?


Una pregunta más en el código siguiente, cuando el hilo se cancela en algún lugar de A , second_thread_cleanup_function () será llamado en primer lugar, ¿verdad?

class SomeObject
{
    public:
        ~SimpleObject (void); // <- free dynamically allocated memory

        void finalize (void);

        // ...
}

void first_thread_cleanup_function (void* argument)
{
    SomeObject* object (argument);

    object->finalize ();
}

void second_thread_cleanup_function (void* argument)
{
    // ... do something ...
}

void* thread_function (viod* argument)
{
    SomeObject object;

    pthread_cleanup_push (first_thread_cleanup_function, &object);

    // ... some code ...

    pthread_cleanup_push (second_thread_cleanup_function, NULL);
    // ... SECTION A ...
    pthread_cleanup_pop (0);

    // .. some code ...

    pthread_cleanup_pop (1);
}
¿Fue útil?

Solución

Con cualquier distribución de Linux moderno usando NPTL (que en la práctica significa cualquier ejecución de un kernel 2.6), NPTL llamará destructores y descansar la pila con un pseudo-excepción.

De hecho NTPL insiste en que, mediante la implementación de lo que llama pila obligado desenrollar. Se puede coger el seudo-excepción con el retén (...), pero si lo hace por lo que posteriormente debe volver a lanzar o será terminado todo el proceso.

Chris

Otros consejos

Los destructores sólo se llama suponiendo que liberará los objetos asignados en los métodos de limpieza. De lo contrario, no.

Y sí, usted tiene el orden de las llamadas de limpieza en la sección A correcta.

La afirmación de que la pila de un hilo cancelada no es desenrollada - que resulta en la no destrucción de objetos locales - es incompatible con la afirmación de que @ Chris pila del hilo se desenrolla y con el contra-ejemplo siguiente:

#include <climits>
#include <iostream>
#include <pthread.h>
#include <thread>
#include <unistd.h>

class Obj {
public:
    Obj()  { std::clog << "Obj() called\n"; }
    ~Obj() { std::clog << "~Obj() called\n"; }
};

static void cleanup(void* arg) {
    std::clog << "cleanup() called\n";
}

static void run() {
    Obj obj{}; // Local object
    pthread_cleanup_push(cleanup, nullptr);
    ::pause(); // Thread cancelled here
    pthread_cleanup_pop(1);
}

int main(int argc, char **argv) {
    std::thread thread([]{run();});
    ::sleep(1);
    ::pthread_cancel(thread.native_handle());
    thread.join();
}

Cuando se ejecuta, el programa anterior indica que destructor del objeto local es, de hecho, llama cuando se cancela el hilo:

$ ./a.out 
Obj() called
cleanup() called
~Obj() called
$ 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top