2009-11-03 29 views

Respuesta

30

Dado que puede unir un hilo incluso después de que haya finalizado, joinable() seguirá siendo verdadero hasta que llame a join() o detach(). Si desea saber si un hilo aún se está ejecutando, debe poder llamar a timed_join con un tiempo de espera de 0. Tenga en cuenta que esto puede dar como resultado una condición de carrera ya que el hilo puede finalizar inmediatamente después de la llamada.

+6

Es un poco engañoso decir que puede dar lugar a una condición de carrera. 'timed_join' solo no puede hacer eso. si hace suposiciones incorrectas basadas en el resultado de la llamada, puede terminar con una condición de carrera, por supuesto, pero eso tiene menos que ver con 'timed_join' que con usted, suponiendo que el resultado de esa llamada aún sea válido. De todos modos, +1 – jalf

+35

Creo que esto es realmente malo. ¿Por qué los diseñadores de impulso nunca piensan en la intuición o de principiantes? Un simple método isRunning() hubiera sido suficiente. En su lugar, obligan a uno a utilizar una función que, intuitivamente, no debería utilizarse en este caso. No quiero intentar unirme al hilo, solo quiero probar rápidamente si aún funciona algo. Esto es una mierda. Perdí mucho tiempo antes de encontrar esto. Ni una maldita palabra en los "documentos" tampoco. – AndreasT

+0

Un hilo puede estar en 3 estados: Correr, Independiente, No ejecutar. –

3

Usted fundamentalmente no puede hacer esto. La razón es que las dos respuestas posibles son "Sí" y "No cuando la vi por última vez, pero quizás ahora". No hay una manera confiable de determinar si un hilo todavía está dentro de su método de ejecución, incluso si hubiera una manera confiable de determinar lo contrario.

+7

Usted fundamentalmente puede hacer esto. Puede consultar u "observar" de forma fiable el estado de un hilo en cualquier momento. El problema es que no se pueden hacer suposiciones para las interacciones basadas en el estado que se obtuvo, lo que significa que en el momento en que se tiene la información "el hilo aún se está ejecutando" ya se pudo haber detenido en el tiempo necesario para obtener esa información, pero eso rara vez es crítico. Lo siento, pero esta publicación no fue de ninguna manera útil. – AndreasT

+0

@Areaspe: Si no puede hacer ninguna suposición, ¿cómo podría ser útil? –

5

Utilice thread::timed_join() con un tiempo de espera mínimo. Devolverá falso si el hilo todavía se está ejecutando.

+0

Esto es falso. Si un hilo se separó, devolverá falso. De hecho, necesita leerlo al revés: si devuelve verdadero el hilo se estaba ejecutando y luego se detuvo durante el tiempo de espera –

+0

@GaetanoMendola: No exactamente, el hilo podría detenerse y unirse cuando llame a timed_join y el resultado sea verdadero. –

0

Esto es un poco crudo pero a partir de ahora todavía está funcionando para mis requisitos. :) Estoy usando boost 153 y qt. Creé un vector de int para rastrear el "estado" de mis hilos. Cada vez que creo un nuevo hilo, agrego una entrada a thread_ids con un valor de 0. Para cada hilo creado, paso una identificación así sé qué parte de thread_ids se supone que debo actualizar. Establezca el estado en 1 para ejecutar y otros valores, dependiendo de la actividad que esté realizando actualmente, así sabré qué actividad se estaba realizando cuando finalizó el hilo. 100 es el valor que configuro para un hilo terminado correctamente. No estoy seguro si esto ayudará, pero si tiene otras sugerencias sobre cómo mejorar esto, hágamelo saber. :)

std::vector<int> thread_ids; 
const int max_threads = 4; 
void Thread01(int n, int n2) 
{ 
    thread_ids.at(n) = 1; 
    boost::this_thread::sleep(boost::posix_time::milliseconds(n2 * 1000)); 
    thread_ids.at(n) = 100; 
    qDebug()<<"Done "<<n; 

} 
void getThreadsStatus() 
{ 
    qDebug()<<"status:"; 
    for(int i = 0; i < max_threads, i < thread_ids.size(); i++) 
    { 
     qDebug()<<thread_ids.at(i); 
    } 
} 
int main(int argc, char *argv[]) 
{ 
    for(int i = 0; i < max_threads; i++) 
    { 
     thread_ids.push_back(0); 
     threadpool.create_thread(
      boost::bind(&boost::asio::io_service::run, &ioService)); 
     ioService.post(boost::bind(Thread01, i, i + 2)); 
     getThreadsStatus(); 
    } 

    ioService.stop(); 
    threadpool.join_all(); 
    getThreadsStatus(); 
} 
0

La forma más fácil, si la función que ejecuta el hilo es bastante simple, es para establecer una variable a cierto cuando se termina la función. Por supuesto, necesitará una variable por hilo, si tiene muchos mapas de identificadores de subprocesos y el estado puede ser una mejor opción. Sé que está hecho a mano, pero funciona bien mientras tanto.

class ThreadCreator 
{ 
private: 
    bool   m_threadFinished; 
    void launchProducerThread(){ 
     // do stuff here 
     m_threadRunning = true; 
    } 
public: 
    ThreadCreator() : m_threadFinished(false) { 
     boost::thread(&Consumer::launchProducerThread, this); 
    } 
}; 
0

esto puede no ser una respuesta directa a su pregunta, pero veo el concepto hilo como un mecanismo muy ligero, e intencionalmente carente de nada, excepto mecanismos de sincronización. Creo que el lugar correcto para poner "se está ejecutando" está en la clase que define la función de subprocesos. Tenga en cuenta que desde una perspectiva de diseño, puede salir del hilo en la interrupción y aún así no completar su trabajo. Si desea limpiar el hilo después de que se haya completado, puede envolverlo en un puntero seguro y entregarlo a la clase de trabajadores.

+0

Creo que sería mejor si usted aclara con ejemplos de código y divide su texto en párrafos para facilitar la lectura. – phaberest

Cuestiones relacionadas