La consecuencia principal es que el hilo puede comenzar a ejecutarse (y usar el puntero) antes de que el constructor haya finalizado, por lo que el objeto puede no estar en un estado definido/utilizable. Del mismo modo, dependiendo de cómo se detiene el subproceso, puede continuar ejecutándose después de que se haya iniciado el destructor y, por lo tanto, es posible que el objeto no esté en un estado utilizable.
Esto es especialmente problemático si su clase es una clase base, ya que el constructor de clase derivado ni siquiera comenzará a ejecutarse hasta que su constructor haya finalizado, y el destructor de clase derivado habrá finalizado antes de que se inicie el suyo. Además, las llamadas a funciones virtuales no hacen lo que se podría pensar antes de construir las clases derivadas y después de destruirlas: las llamadas virtuales "ignoran" las clases cuya parte del objeto no existe.
Ejemplo:
struct BaseThread {
MyThread() {
pthread_create(thread, attr, pthread_fn, static_cast<void*>(this));
}
virtual ~MyThread() {
maybe stop thread somehow, reap it;
}
virtual void id() { std::cout << "base\n"; }
};
struct DerivedThread : BaseThread {
virtual void id() { std::cout << "derived\n"; }
};
void* thread_fn(void* input) {
(static_cast<BaseThread*>(input))->id();
return 0;
}
Ahora bien, si se crea un DerivedThread, es una mejor una carrera entre el hilo que lo construye y el nuevo hilo, para determinar qué versión de id()
es llamada. Podría ser que algo peor pueda pasar, necesitarías mirar muy de cerca tu API y compilador.
La forma habitual de no tener que preocuparse por esto es simplemente dar a su clase de subproceso una función start()
, que el usuario llama después de construirla.
@gilbertc: Si B deriva de A, incluso si inicia el subproceso al final del constructor de A, todo iniciará/ejecutará desde B (vtable, variables miembro, código de constructor). ¿Podría ser esto un desagradable error de concurrencia? A primera vista, diría que sí, porque el objeto cambiará en el hilo de construcción, mientras que podría usarse en el hilo recién creado. – paercebal