Multithreading : création de threads de travail dans MFC
Un thread de travail est couramment utilisé pour gérer les tâches en arrière-plan que l’utilisateur ne doit pas avoir à attendre pour continuer à utiliser votre application. Les tâches telles que le recalcul et l’impression en arrière-plan sont de bons exemples de threads de travail. Cette rubrique détaille les étapes nécessaires pour créer un thread de travail. Les sujets abordés sont les suivants :
La création d’un thread de travail est une tâche relativement simple. Seules deux étapes sont nécessaires pour exécuter votre thread : implémentation de la fonction de contrôle et démarrage du thread. Il n’est pas nécessaire de dériver une classe de CWinThread. Vous pouvez dériver une classe si vous avez besoin d’une version spéciale de CWinThread
, mais elle n’est pas nécessaire pour la plupart des threads de travail simples. Vous pouvez utiliser CWinThread
sans modification.
Démarrage du thread
Il existe deux versions surchargées de AfxBeginThread
: une qui ne peut créer que des threads de travail, et une qui peut créer des threads d’interface utilisateur et des threads de travail. Pour commencer l’exécution de votre thread de travail à l’aide de la première surcharge, appelez AfxBeginThread, en fournissant les informations suivantes :
Adresse de la fonction de contrôle.
Paramètre à passer à la fonction de contrôle.
(Facultatif) Priorité souhaitée du thread. La priorité par défaut est normale. Pour plus d’informations sur les niveaux de priorité disponibles, consultez SetThreadPriority dans le Kit de développement logiciel (SDK) Windows.
(Facultatif) Taille de pile souhaitée pour le thread. La valeur par défaut est la même pile de tailles que le thread de création.
(Facultatif) CREATE_SUSPENDED si vous souhaitez que le thread soit créé dans un état suspendu. La valeur par défaut est 0 ou démarre le thread normalement.
(Facultatif) Attributs de sécurité souhaités. La valeur par défaut est le même accès que le thread parent. Pour plus d’informations sur le format de ces informations de sécurité, consultez SECURITY_ATTRIBUTES dans le Kit de développement logiciel (SDK) Windows.
AfxBeginThread
crée et initialise un CWinThread
objet pour vous, le démarre et retourne son adresse afin que vous puissiez vous y référer ultérieurement. Les vérifications sont effectuées tout au long de la procédure pour s’assurer que tous les objets sont désalloués correctement si une partie de la création échoue.
Implémentation de la fonction de contrôle
La fonction de contrôle définit le thread. Lorsque cette fonction est entrée, le thread démarre et, lorsqu’il se termine, le thread se termine. Cette fonction doit avoir le prototype suivant :
UINT MyControllingFunction( LPVOID pParam );
Le paramètre est une valeur unique. La valeur que la fonction reçoit dans ce paramètre est la valeur qui a été passée au constructeur lors de la création de l’objet thread. La fonction de contrôle peut interpréter cette valeur de n’importe quelle manière qu’elle choisit. Elle peut être traitée comme une valeur scalaire ou un pointeur vers une structure contenant plusieurs paramètres, ou elle peut être ignorée. Si le paramètre fait référence à une structure, la structure peut être utilisée non seulement pour transmettre des données de l’appelant au thread, mais également pour transmettre des données du thread à l’appelant. Si vous utilisez une telle structure pour transmettre des données à l’appelant, le thread doit notifier l’appelant lorsque les résultats sont prêts. Pour plus d’informations sur la communication du thread de travail vers l’appelant, consultez Multithreading : Conseils de programmation.
Lorsque la fonction se termine, elle doit retourner une valeur UINT indiquant la raison de l’arrêt. En règle générale, ce code de sortie est 0 pour indiquer la réussite avec d’autres valeurs indiquant différents types d’erreurs. Cela dépend uniquement de l’implémentation. Certains threads peuvent conserver le nombre d’objets d’utilisation et retourner le nombre actuel d’utilisations de cet objet. Pour voir comment les applications peuvent récupérer cette valeur, consultez Multithreading : Fin des threads.
Il existe des restrictions sur ce que vous pouvez faire dans un programme multithread écrit avec la bibliothèque MFC. Pour obtenir des descriptions de ces restrictions et d’autres conseils sur l’utilisation de threads, consultez Multithreading : Conseils de programmation.
Contrôle de l’exemple de fonction
L’exemple suivant montre comment définir une fonction de contrôle et l’utiliser à partir d’une autre partie du programme.
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);
.
.
.