Question

J'écris programme de MT pour Linux en C ++ et je veux savoir comment l'annulation de thread est exécuté.

Pour autant que je comprends lorsque le fil est des fonctions de nettoyage annulées sont appelées à l'intérieur de la fonction de fil et la fonction du fil est forcé de sortir. Ces deux moyennes choses:

  1. Lorsque thread est annulé, il appelle encore tous les fo Destructeurs C ++ Les objets créés dans la fonction de fil.
  2. je peux passer à des fonctions de nettoyage des pointeurs vers des objets créés dans la fonction de fil.

Ai-je raison et le code ci-dessous fonctionnent mal très bien?


Une autre question dans le code ci-dessous, lorsque le fil est annulé quelque part dans A , second_thread_cleanup_function () sera appelé d'abord, à droite?

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);
}
Était-ce utile?

La solution

Avec une distribution Linux moderne en utilisant NPTL (qui signifie en pratique toute exécution d'un noyau 2.6), NPTL appellera et se détendre Destructeurs la pile avec une pseudo-exception.

En fait NPTL insiste sur ce point, en mettant en place ce qu'il appelle pile forcé le déroulement. Vous pouvez prendre le pseudo-exception avec catch (...), mais si vous le faites, vous devez ensuite réémettre ou tout le processus sera terminé.

Chris

Autres conseils

Destructeurs ne sera appelé en supposant que vous libérer des objets affectés dans les méthodes de nettoyage. Dans le cas contraire, non.

Et oui, vous avez l'ordre des appels de nettoyage dans la section A correcte.

L'affirmation selon laquelle une pile de fil d'annulation est pas déroulée - conduisant à la non-destruction d'objets locaux - est incompatible avec l'affirmation @ Chris que la pile du fil est déroulé et avec le contre-exemple suivant:

#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();
}

Lors de son exécution, le programme ci-dessus indique que la destructor de l'objet local est, en effet, appelée lorsque le thread est annulé:

$ ./a.out 
Obj() called
cleanup() called
~Obj() called
$ 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top