Grupos de subprocesos

Un grupo de subprocesos es una colección de subprocesos de trabajo que ejecutan de forma eficaz devoluciones de llamada asincrónicas en nombre de la aplicación. El grupo de subprocesos se usa principalmente para reducir el número de subprocesos de aplicación y proporcionar administración de los subprocesos de trabajo. Las aplicaciones pueden poner en cola elementos de trabajo, asociar el trabajo con identificadores de espera, poner en cola automáticamente en función de un temporizador y enlazar con E/S.

Arquitectura del grupo de subprocesos

Las siguientes aplicaciones pueden beneficiarse del uso de un grupo de subprocesos:

  • Una aplicación que es muy paralela y puede enviar un gran número de elementos de trabajo pequeños de forma asincrónica (como búsqueda de índices distribuidos o E/S de red).
  • Una aplicación que crea y destruye un gran número de subprocesos que se ejecutan durante un breve tiempo. El uso del grupo de subprocesos puede reducir la complejidad de la administración de subprocesos y la sobrecarga implicada en la creación y destrucción de subprocesos.
  • Una aplicación que procesa elementos de trabajo independientes en segundo plano y en paralelo (como cargar varias pestañas).
  • Una aplicación que debe realizar una espera exclusiva en objetos kernel o bloquear eventos entrantes en un objeto. El uso del grupo de subprocesos puede reducir la complejidad de la administración de subprocesos y aumentar el rendimiento al reducir el número de modificadores de contexto.
  • Una aplicación que crea subprocesos de espera personalizados para esperar en eventos.

El grupo de subprocesos original se ha rediseñado completamente en Windows Vista. El nuevo grupo de subprocesos se ha mejorado porque proporciona un único tipo de subproceso de trabajo (admite E/S y no E/S), no usa un subproceso de temporizador, proporciona una sola cola de temporizador y proporciona un subproceso persistente dedicado. También proporciona grupos de limpieza, un mayor rendimiento, varios grupos por proceso programados de forma independiente y una nueva API de grupo de subprocesos.

La arquitectura del grupo de subprocesos consta de lo siguiente:

  • Subprocesos de trabajo que ejecutan las funciones de devolución de llamada
  • Subprocesos de waiter que esperan en varios identificadores de espera
  • Una cola de trabajo
  • Un grupo de subprocesos predeterminado para cada proceso
  • Generador de trabajo que administra los subprocesos de trabajo

Prácticas recomendadas

La nueva API del grupo de subprocesos proporciona más flexibilidad y control que la API del grupo de subprocesos original. Sin embargo, hay algunas diferencias sutiles pero importantes. En la API original, el restablecimiento de espera era automático; en la nueva API, la espera debe restablecerse explícitamente cada vez. La API original controló la suplantación automáticamente, transfiriendo el contexto de seguridad del proceso de llamada al subproceso. Con la nueva API, la aplicación debe establecer explícitamente el contexto de seguridad.

Estos son los procedimientos recomendados al usar un grupo de subprocesos:

  • Los subprocesos de un proceso comparten el grupo de subprocesos. Un único subproceso de trabajo puede ejecutar varias funciones de devolución de llamada, de una en una. El grupo de subprocesos administra estos subprocesos de trabajo. Por lo tanto, no finalice un subproceso del grupo de subprocesos llamando a TerminateThread en el subproceso o llamando a ExitThread desde una función de devolución de llamada.

  • Una solicitud de E/S se puede ejecutar en cualquier subproceso del grupo de subprocesos. La cancelación de E/S en un subproceso del grupo de subprocesos requiere sincronización porque la función cancel se puede ejecutar en un subproceso diferente al que controla la solicitud de E/S, lo que puede dar lugar a la cancelación de una operación desconocida. Para evitar esto, proporcione siempre la estructura SUPERPUESTA con la que se inició una solicitud de E/S al llamar a CancelIoEx para E/S asincrónica, o use su propia sincronización para asegurarse de que no se puede iniciar ninguna otra E/S en el subproceso de destino antes de llamar a la función CancelSynchronousIo o CancelIoEx .

  • Limpie todos los recursos creados en la función de devolución de llamada antes de volver de la función. Entre ellos se incluyen TLS, contextos de seguridad, prioridad de subprocesos y registro COM. Las funciones de devolución de llamada también deben restaurar el estado del subproceso antes de devolver.

  • Mantenga activos los identificadores de espera y sus objetos asociados hasta que el grupo de subprocesos haya señalado que ha terminado con el identificador .

  • Marque todos los subprocesos que están esperando operaciones largas (como vaciados de E/S o limpieza de recursos) para que el grupo de subprocesos pueda asignar nuevos subprocesos en lugar de esperar a este.

  • Antes de descargar un archivo DLL que usa el grupo de subprocesos, cancelar todos los elementos de trabajo, E/S, operaciones de espera y temporizadores, y esperar a que se completen las devoluciones de llamada.

  • Evite interbloqueos eliminando las dependencias entre los elementos de trabajo y entre devoluciones de llamada, asegurándose de que una devolución de llamada no está esperando a completarse y conservando la prioridad del subproceso.

  • No ponga en cola demasiados elementos en un proceso con otros componentes mediante el grupo de subprocesos predeterminado. Hay un grupo de subprocesos predeterminado por proceso, incluido Svchost.exe. De forma predeterminada, cada grupo de subprocesos tiene un máximo de 500 subprocesos de trabajo. El grupo de subprocesos intenta crear más subprocesos de trabajo cuando el número de subprocesos de trabajo en estado listo o en ejecución debe ser menor que el número de procesadores.

  • Evite el modelo de apartamento de un solo subproceso COM, ya que no es compatible con el grupo de subprocesos. STA crea el estado del subproceso que puede afectar al siguiente elemento de trabajo para el subproceso. STA suele ser de larga duración y tiene afinidad de subproceso, que es lo contrario al grupo de subprocesos.

  • Cree un nuevo grupo de subprocesos para controlar la prioridad y el aislamiento del subproceso, crear características personalizadas y, posiblemente, mejorar la capacidad de respuesta. Sin embargo, los grupos de subprocesos adicionales requieren más recursos del sistema (subprocesos, memoria del kernel). Demasiados grupos aumenta la posibilidad de contención de CPU.

  • Si es posible, use un objeto waitable en lugar de un mecanismo basado en APC para indicar un subproceso del grupo de subprocesos. Las API no funcionan también con subprocesos del grupo de subprocesos como otros mecanismos de señalización porque el sistema controla la duración de los subprocesos del grupo de subprocesos, por lo que es posible que un subproceso finalice antes de que se entregue la notificación.

  • Use la extensión del depurador del grupo de subprocesos, !tp. Este comando tiene el siguiente uso:

    • marcasde dirección del grupo
    • marcas de dirección obj
    • Marcas de dirección de tqueue
    • dirección del waiter
    • dirección de trabajo

    En el caso del grupo, el waiter y el trabajo, si la dirección es cero, el comando volca todos los objetos. Para el waiter y el trabajo, omite los volcados de dirección del subproceso actual. Se definen las marcas siguientes: 0x1 (salida de una sola línea), 0x2 (miembros de volcado) y 0x4 (cola de trabajo del grupo de volcados).

API de grupo de subprocesos

Uso de las funciones del grupo de subprocesos