2010-07-01 13 views
13

Las API de subprocesos de Windows y Solaris permiten que se cree un subproceso en estado "suspendido". El hilo solo comienza realmente cuando luego se "reanuda". Estoy acostumbrado a los hilos POSIX que no tienen este concepto, y estoy luchando para entender la motivación para ello. ¿Alguien puede sugerir por qué sería útil crear un hilo "suspendido"?¿Por qué querría comenzar un hilo "suspendido"?

Aquí hay un ejemplo ilustrativo simple. WinAPI me permite hacer esto:

t = CreateThread(NULL,0,func,NULL,CREATE_SUSPENDED,NULL); 
// A. Thread not running, so do... something here? 
ResumeThread(t); 
// B. Thread running, so do something else. 

El (simple) POSIX equivalente parece ser:

// A. Thread not running, so do... something here? 
pthread_create(&t,NULL,func,NULL); 
// B. Thread running, so do something else. 

¿alguien tiene alguna ejemplos del mundo real en el que hemos sido capaces de hacer algo en el punto A (entre CreateThread & ResumeThread) ¿cuál hubiera sido difícil en POSIX?

+1

Ah, claro, entiendo que usar CreateThread directamente no es realmente lo que se supone que se debe hacer desde C/C++ - no le da al C-Runtime la oportunidad de inicializar varias cosas de la limpieza. _beginthreadex debería usarse en su lugar (o eso es lo que leo) – Ragster

+0

Implementar dicho mecanismo en POSIX no sería difícil. Tendría que usar simple pthread_cond_wait – adf88

+0

@Ragster - gracias por la sugerencia. _beginthreadex() es de hecho la forma correcta de iniciar un hilo en Windows. –

Respuesta

22
  1. Para preasignar recursos y luego iniciar el hilo casi de inmediato.
  2. Tiene un mecanismo que reutiliza un hilo (lo reanuda), pero no tiene un hilo para reutilizar y debe crear uno.
+0

+1 esas son buenas razones para ello. – stinky472

+0

Ambas respuestas implican que es costoso crear un hilo. He tenido un poke en Google y descubrí que tanto Windows como Linux toman ~ 0.2ms para crear un hilo. Eso es de hecho bastante costoso. –

+0

Repetido varias veces puede ser un costo grave. – adf88

8

Puede ser útil para crear un hilo en un estado suspendido en muchas instancias (me parece) - es posible que desee obtener el mango y establecer algunas de sus propiedades antes de permitir que comience a utilizar los recursos estás preparándote para eso.

El inicio suspendido es mucho más seguro que iniciarlo y luego suspenderlo: no tiene idea de lo lejos que está o de lo que está haciendo.

Otro ejemplo podría ser cuando desee utilizar un grupo de subprocesos: crea los hilos necesarios por adelantado, se suspende y, cuando llega una solicitud, seleccione uno de los subprocesos, establezca la información del subproceso para la tarea, y luego establecerlo como programable.

Me atrevo a decir que hay maneras de evitar tener CREATE_SUSPENDED, pero ciertamente tiene sus aplicaciones.

¡Hay algunos ejemplos de usos en 'Windows a través de C/C++' (Richter/Nasarre) si quiere muchos detalles!

1

Me tropecé con un problema similar una vez. Las razones para el estado inicial suspendido se tratan en otra respuesta.

Mi solución con pthread era utilizar un mutex y cond_wait, pero no sé si es una buena solución y si puede cubrir todas las necesidades posibles. No sé, además, si el hilo puede considerarse suspendido (en ese momento, consideré "bloqueado" en el manual como un sinónimo, pero probablemente no sea así)

3

Es posible que desee iniciar un hilo con alguna otra prioridad (generalmente más baja) o con una máscara de afinidad específica. Si lo genera como de costumbre, puede ejecutarse con prioridad/afinidad indeseada durante algún tiempo. Entonces lo comienzas suspendido, cambias los parámetros que deseas y luego reanudas el hilo.

+0

Eso sugiere que lo necesita para evitar deficiencias en el WinAPI. ¡Todos esos parámetros para CreateThread() y usted * todavía * no pueden crear el hilo que desea!

2

Los hilos que usamos son capaces de intercambiar mensajes, y tenemos colas de mensajes heredadas de prioridad configurables arbitrariamente (descritas en el archivo de configuración) que conectan esos hilos. Hasta que cada cola se haya construido y conectado a cada hilo, no podemos permitir que los hilos se ejecuten, ya que comenzarán a enviar mensajes a ninguna parte y esperan respuestas. Hasta que se construyó cada hilo, no podemos construir las colas, ya que necesitan unirse a algo.Por lo tanto, no se puede permitir que ningún subproceso haga trabajo hasta que se haya configurado el último. Usamos boost.threads, y lo primero que hacen es esperar en un boost::barrier.

3

Hay una condición de carrera implícita en CreateThread: no puede obtener la ID de hilo hasta después de el hilo comenzó a ejecutarse. Es completamente impredecible cuando regresa la llamada, por lo que usted sabe, el hilo podría haberse completado. Si el hilo causa alguna interacción en el resto del proceso que requiere el TID, entonces tienes un problema.

No es un problema sin solución si la API no admite iniciar el hilo suspendido, simplemente tiene el bloque de hilos en un mutex de inmediato y libere ese mutex después de que la llamada CreateThread regrese.

Sin embargo, hay otro uso para CREATE_SUSPENDED en la API de Windows que es muy difícil de tratar si falta el soporte de API. La llamada CreateProcess() también acepta esta bandera, suspende el hilo de inicio del proceso. El mecanismo es idéntico, el proceso se carga y obtendrás un PID pero no se ejecutará ningún código hasta que liberes el hilo de inicio. Eso es muy útil. Utilicé esta característica para configurar un protector de procesos que detecta fallas en el proceso y crea un minivolcado. El indicador CREATE_SUSPEND me permitió detectar y tratar las fallas de inicialización, normalmente muy difíciles de solucionar.

+0

pthreads no sufre de esa raza, ya que el ID de hilo se establece por referencia. pthread_create() puede garantizar que la ID del hilo esté establecida antes de que comience el hilo. La interfaz CreateThread() tiene ese problema, por lo que puedo ver que podría ser necesario para "iniciar suspendido". –

+1

Hmm, también se establece por referencia en CreateThread. No estoy seguro de qué pollo es el primero. –

Cuestiones relacionadas