Multithreading: Crear subprocesos de trabajo en MFC

Un subproceso de trabajo se usa normalmente para controlar las tareas en segundo plano que el usuario no debe tener que esperar a fin de seguir usando la aplicación. Tareas como el recálculo y la impresión en segundo plano son buenos ejemplos de subprocesos de trabajo. En este tema se detallan los pasos necesarios para crear un subproceso de trabajo. Contenido de los temas:

La creación de un subproceso de trabajo es una tarea relativamente sencilla. Solo se necesitan dos pasos para que el subproceso se ejecute: implementar la función de control e iniciar el subproceso. No es necesario derivar una clase de CWinThread. Puede derivar una clase si necesita una versión especial de CWinThread, pero para la mayoría de los subprocesos de trabajo sencillos no es necesaria. Puede usar CWinThread sin agregar modificaciones.

Inicio del subproceso

Hay dos versiones sobrecargadas de AfxBeginThread: una que solo puede crear subprocesos de trabajo y otra que puede crear subprocesos de interfaz de usuario y subprocesos de trabajo. Para comenzar la ejecución del subproceso de trabajo mediante la primera sobrecarga, llame a AfxBeginThread y proporcione la información siguiente:

  • Dirección de la función de control.

  • Parámetro que se va a pasar a la función de control.

  • (Opcional) Prioridad deseada del subproceso. El valor predeterminado es la prioridad normal. Para obtener más información acerca de los niveles de prioridad disponibles, vea SetThreadPriority en Windows SDK.

  • (Opcional) El tamaño de pila deseado para el subproceso. El valor predeterminado para el tamaño de pila es el mismo que el del subproceso creador.

  • (Opcional) CREATE_SUSPENDED si desea que el subproceso se cree en un estado suspendido. El valor predeterminado es 0, es decir, iniciar el subproceso normalmente.

  • (Opcional) Los atributos de seguridad deseados. El valor predeterminado es el mismo acceso que el de su subproceso primario. Para obtener más información acerca del formato de esta información de seguridad, vea SECURITY_ATTRIBUTES en Windows SDK.

AfxBeginThread crea e inicializa un objeto CWinThread automáticamente, lo inicia y devuelve su dirección para que pueda hacer referencia a él más adelante. Se realizan comprobaciones en todo el procedimiento para asegurar que todos los objetos queden desasignados correctamente en caso de error en algún momento del proceso de creación.

Implementación de la función de control

La función de control define el subproceso. Cuando se introduce esta función, el subproceso se inicia y, cuando se cierra, el subproceso finaliza. Esta función debe tener el prototipo siguiente:

UINT MyControllingFunction( LPVOID pParam );

El parámetro es un valor único. El valor que recibe la función en este parámetro es el valor que se pasó al constructor cuando se creó el objeto de subproceso. La función de control puede interpretar este valor de la manera que elija. Se puede tratar como un valor escalar o un puntero a una estructura que contiene varios parámetros, o bien se puede omitir. Si el parámetro hace referencia a una estructura, esta se puede usar no solo para pasar datos del autor de la llamada al subproceso, sino también para devolver datos del subproceso al autor de la llamada. Si usa esta estructura para devolver datos al autor de la llamada, el subproceso debe notificar al autor de la llamada cuando estén listos los resultados. Para obtener información sobre cómo comunicarse desde el subproceso de trabajo al autor de la llamada, vea Multithreading: Sugerencias de programación.

Cuando finaliza la función, debe devolver un valor UINT que indique el motivo de la finalización. Normalmente, este código de salida es 0 para indicar que se ha hecho correctamente con otros valores que indican distintos tipos de errores. Esto depende exclusivamente de la implementación. Algunos subprocesos pueden mantener recuentos de uso de objetos y devolver el número actual de usos de ese objeto. Para ver cómo las aplicaciones pueden recuperar este valor, vea Multithreading: Finalizar subprocesos.

Hay algunas restricciones respecto a lo que puede hacer en un programa multiproceso escrito con la biblioteca MFC. Para obtener descripciones de estas restricciones y otras sugerencias sobre el uso de subprocesos, vea Multithreading: Sugerencias de programación.

Ejemplo de función de control

En el ejemplo siguiente se muestra cómo definir una función de control y cómo usarla desde otra parte del programa.

UINT MyThreadProc( LPVOID pParam )
{
    CMyObject* pObject = (CMyObject*)pParam;

    if (pObject == NULL ||
        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))
    return 1;   // if pObject is not valid

    // do something with 'pObject'

    return 0;   // thread completed successfully
}

// inside a different function in the program
.
.
.
pNewObject = new CMyObject;
AfxBeginThread(MyThreadProc, pNewObject);
.
.
.

¿Qué más desea saber?

Consulte también

Multithreading con C++ y MFC