Far passare la cancellazione (pthread) & C ++
-
26-09-2019 - |
Domanda
Sto scrivendo programma di MT per Linux in C ++ e voglio sapere come viene eseguita la cancellazione thread.
Per quanto comprendo quando il filo è cancellata funzioni di pulizia vengono chiamate all'interno funzione del filo e la funzione del filo è costretto a uscire. Questo significa due cose:
- Quando il filo viene annullata chiama ancora distruttori fo tutti C ++ oggetti creati all'interno funzione del thread.
- I può passare a funzioni di pulizia puntatori a oggetti creati in funzione del thread.
Ho ragione e il codice sottostante il lavoro male che bene?
Ancora una domanda in codice qui sotto, quando il filo viene annullata da qualche parte nel A , second_thread_cleanup_function () sarà chiamato prima, giusto?
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);
}
Soluzione
Con qualsiasi moderna distribuzione Linux usando NPTL (che in pratica significa qualsiasi esecuzione di un kernel 2.6), NPTL chiamerà distruttori e distendersi lo stack con uno pseudo-eccezione.
Infatti NPTL insiste su di esso, attuando ciò che definisce pila forzato svolgimento. È possibile prendere la pseudo-eccezione con catch (...), ma se lo fate è necessario in seguito rigenerare o l'intero processo sarà terminato.
Chris
Altri suggerimenti
I distruttori sarà chiamato solo a patto di liberare gli oggetti allocati nei metodi di pulizia. In caso contrario, no.
E sì, avete l'ordine delle chiamate di pulizia nella sezione A corretta.
L'asserzione che stack di un thread cancellato non viene srotolato - conseguente non distruzione di oggetti locali - è incompatibile con l'affermazione @ Chris che stack del thread viene svolta e con il seguente controesempio:
#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();
}
Quando viene eseguito, il programma precedente indica che il distruttore dell'oggetto locale è, infatti, chiamata quando il filo viene annullata:
$ ./a.out
Obj() called
cleanup() called
~Obj() called
$