Multithreading : fin des threads dans MFC

Deux situations normales entraînent l’arrêt d’un thread : la fonction de contrôle s’arrête ou le thread n’est pas autorisé à s’exécuter jusqu’à la fin. Si un processeur de texte a utilisé un thread pour l’impression en arrière-plan, la fonction de contrôle se termine normalement si l’impression s’est terminée avec succès. Si l’utilisateur souhaite annuler l’impression, toutefois, le thread d’impression en arrière-plan doit être arrêté prématurément. Cette rubrique explique à la fois comment implémenter chaque situation et comment obtenir le code de sortie d’un thread après son arrêt.

Arrêt normal du thread

Pour un thread de travail, l’arrêt normal du thread est simple : quittez la fonction de contrôle et retournez une valeur qui signifie la raison de l’arrêt. Vous pouvez utiliser la fonction AfxEndThread ou une return instruction. En règle générale, 0 signifie la réussite, mais c’est à vous.

Pour un thread d’interface utilisateur, le processus est tout aussi simple : à partir du thread d’interface utilisateur, appelez PostQuitMessage dans le Kit de développement logiciel (SDK) Windows. Le seul paramètre qui PostQuitMessage prend est le code de sortie du thread. Comme pour les threads de travail, 0 signifie généralement la réussite.

Arrêt prématuré du thread

La fin d’un thread prématurément est presque aussi simple : appelez AfxEndThread à partir du thread. Transmettez le code de sortie souhaité comme seul paramètre. Cela arrête l’exécution du thread, libère la pile du thread, détache toutes les DLL attachées au thread et supprime l’objet thread de la mémoire.

AfxEndThread doit être appelé à partir du thread à arrêter. Si vous souhaitez arrêter un thread à partir d’un autre thread, vous devez configurer une méthode de communication entre les deux threads.

Récupération du code de sortie d’un thread

Pour obtenir le code de sortie du thread worker ou de l’interface utilisateur, appelez la fonction GetExitCodeThread . Pour plus d’informations sur cette fonction, consultez le Kit de développement logiciel (SDK) Windows. Cette fonction prend le handle sur le thread (stocké dans le m_hThread membre de données des CWinThread objets) et l’adresse d’un DWORD.

Si le thread est toujours actif, GetExitCodeThread place STILL_ACTIVE dans l’adresse DWORD fournie ; sinon, le code de sortie est placé dans cette adresse.

La récupération du code de sortie des objets CWinThread prend une étape supplémentaire. Par défaut, lorsqu’un CWinThread thread se termine, l’objet thread est supprimé. Cela signifie que vous ne pouvez pas accéder au m_hThread membre de données, car l’objet CWinThread n’existe plus. Pour éviter cette situation, effectuez l’une des opérations suivantes :

  • Définissez le membre de m_bAutoDelete données sur FALSE. Cela permet à l’objet CWinThread de survivre après l’arrêt du thread. Vous pouvez ensuite accéder au m_hThread membre de données après l’arrêt du thread. Toutefois, si vous utilisez cette technique, vous êtes responsable de la destruction de l’objet CWinThread , car l’infrastructure ne la supprime pas automatiquement pour vous. Ceci est la méthode privilégiée.

  • Stockez le handle du thread séparément. Une fois le thread créé, copiez son m_hThread membre de données (en utilisant ::DuplicateHandle) vers une autre variable et accédez-y via cette variable. De cette façon, l’objet est supprimé automatiquement lorsque l’arrêt se produit et vous pouvez toujours déterminer pourquoi le thread s’est arrêté. Veillez à ce que le thread ne se termine pas avant de pouvoir dupliquer le handle. La méthode la plus sûre consiste à passer CREATE_SUSPENDED à AfxBeginThread, stocker le handle, puis reprendre le thread en appelant ResumeThread.

L’une ou l’autre méthode vous permet de déterminer pourquoi un CWinThread objet s’est arrêté.

Voir aussi

Multithreading à l’aide de C++ et de MFC
_endthread, _endthreadex
_beginthread, _beginthreadex
ExitThread