Comment tuer un fil en c++?

Comment tuer un fil en c++?
Eh bien, vous ne devriez pas tuer un fil dans son exécution pour les raisons suivantes:
  • Un thread a peut-être ouvert un fichier pour l'écriture, et s'il est tué, le fichier ne serait pas fermé. C'est du problème.
  • Un fil aurait pu acquérir un verrou sur les ressources informatiques pour son utilisation unique. Si le fil est tué, les ressources resteront verrouillées et d'autres threads et processus ne pourront pas utiliser les ressources.
  • La mémoire allouée doit être publiée. Le fil aurait pu attribuer une certaine mémoire dans un certain but. Si le fil est tué, la mémoire restera faussement allouée et indisponible pour d'autres threads et processus. C'est une fuite de mémoire.

Ces raisons et tout autre signifient que, si un fil est tué, des ressources qu'elle aurait pu acquérir ne serait pas publiée pour une utilisation par d'autres threads et processus. Lorsqu'un fil se termine naturellement, toute ressource acquise est publiée.

Le motif typique de tuer un thread est que l'utilisateur n'a plus besoin du résultat du thread.

Il y a de bonnes nouvelles: C ++ 20 est la dernière version de C ++ aujourd'hui. La classe de threads de C ++ 20 a des composants pour libérer les ressources, d'un fil, avant sa fin naturelle et l'arrêter avant sa fin naturelle. De cette façon, C ++ arrête le fil et ne tue pas le fil. Autrement dit, C ++ 20 tue le fil de manière responsable. La libération des ressources et l'arrêt du fil sont automatiques. Remarque: tous les threads ne peuvent pas être arrêtés de cette façon. Ces fils se termineraient naturellement, même si une tentative est faite pour les arrêter.

La bibliothèque de thread a les classes suivantes pour s'arrêter avec la publication de ressources: stop_token, stop_source et stop_callback. Chacune de ces classes peut avoir des objets instanciés. Cependant, seuls stop_token et stop_source sont pris en compte dans ce tutoriel.

La commande pour exécuter un programme de threads, avec le compilateur G ++, pour C + 20, devrait être similaire à:

g ++ -std = c ++ 2a temp.cpp -lpthread -o temp

Ce tutoriel explique comment arrêter un fil avec des ressources publiées. Arrêter un fil avec des ressources libéré est un moyen responsable de tuer un fil. Ce tutoriel commence par un résumé de la morue d'un fil.

Contenu de l'article

  • Résumé du codage du thread
  • La classe Jthread
  • Demande d'arrêter un fil
  • Est un arrêt possible?
  • La demande d'arrêt a-t-elle été faite?
  • Conclusion

Résumé du codage du thread

Un programme en cours d'exécution en C ++ est un processus. Un fil est un sous-processus d'un processus. Un programme C ++ simple n'a qu'un seul thread, qui est la fonction principale (). La fonction Main () n'est pas un thread officiellement déclaré. Tout autre fil pour le même programme doit être officiellement déclaré. Il peut y avoir plus d'un fil dans un programme.

Un thread est instancié à partir d'une classe de threads de la bibliothèque de threads. Le premier argument de la déclaration d'un objet de thread est le nom d'une fonction de niveau supérieur. La fonction de niveau supérieur est le thread efficace. Lorsque l'objet est instancié, la fonction de niveau supérieur commence à s'exécuter (en cours d'exécution).

Il y a un fil d'appel et un fil appelé. Malheureusement, si le thread appelé n'est pas joint à partir du corps de fonction du thread appelé, le thread d'appel peut compléter son exécution sans que le thread appelé n'ait terminé sa propre exécution. Cela signifie des ennuis. Ainsi, le corps de fonction du thread d'appel doit toujours rejoindre le fil appelé après l'instanciation du fil appelé.

Dans le programme suivant, un objet de thread est instancié, en utilisant la fonction de niveau supérieur, fn ():

#inclure
#inclure
Utilisation de Namespace Std;
void fn ()
couter <<"first code segment of thread" <couter <<"second code segment of thread" <
int main()

thread thr (fn);
thr.rejoindre();
retour 0;

La sortie est:

premier segment de code du thread
Deuxième segment de code du thread

Notez l'inclusion de la bibliothèque de threads. Notez comment les première et deuxième instructions de la fonction principale ont été codées. La fonction principale () est le thread principal. fn () est une fonction de niveau supérieur.

La classe Jthread

Le jthread est une classe définie dans la bibliothèque de threads. C'est comme la classe de thread mais a l'avantage qu'il peut être utilisé pour arrêter un fil en libérant des ressources. Il a des fonctions membres pour retourner un objet stop_token et un objet stop_source. Les fonctions des membres sont:

stop_source get_stop_source ()
stop_token get_stop_token ()

Il a également la fonction du membre pour faire une demande d'arrêt, qui est:

bool request_stop ()

À l'heure actuelle, en octobre 2021, de nombreux compilateurs C ++ mettent toujours en œuvre la classe Jthread. Cependant, les échantillons de code ci-dessous devraient fonctionner lorsque votre compilateur a implémenté la classe Jthread.

Demande d'arrêter un fil

L'arrêt du fil signifie arrêter la fonction de niveau supérieur de l'exécution. Une demande d'arrêt signifie que le fil doit s'arrêter dès que possible. Si la demande n'est pas accordée, le thread se terminera jusqu'à l'achèvement et ne s'arrête pas avant sa fin.

Comme indiqué ci-dessus, un thread instancié du Jthread a les fonctionnalités pour tuer un fil de manière responsable (empêcher un fil de libération de ses ressources). La fonction membre pour demander cet arrêt est:

bool request_stop ()

La valeur de retour est vraie si la demande a été acceptée et fausse autrement. Accepter la demande ne garantit pas que le fil s'arrêtera dès que possible. Il peut ne pas être possible de mettre en œuvre la demande, et le fil ne s'arrêtera pas avant sa fin naturelle. C'est-à-dire que le retour vrai ne signifie pas que l'arrêt est possible. Le programme suivant illustre l'utilisation de cette fonction membre de l'objet Jthread:

#inclure
#inclure
Utilisation de Namespace Std;
void fn ()
couter <<"first code segment of thread" <couter <<"second code segment of thread" <
int main()

Jthread thr (fn);
thr.request_stop ();
thr.rejoindre();
retour 0;

Ce programme est similaire à ce qui précède, mais pour deux points:

  • Le fil, thr est instancié de la classe Jthread.
  • La déclaration (demande) pour arrêter le thread dès que possible est placée avant l'instruction JOIN (). Dans ce cas, le thread d'appel doit empêcher le thread appelé de continuer à exécuter.

Est un arrêt possible?

Dans certaines situations, il n'est pas possible d'arrêter un fil. Cependant, le programmeur ne peut pas savoir si un fil peut être arrêté ou non. Dans ce cas, le programmeur doit se renseigner. Le stop_source a la fonction membre,

bool stop_posible () const

Si la valeur de retour est vraie, il est possible d'arrêter le fil avant sa fin naturelle. Si la valeur de retour est fausse, il est impossible d'arrêter le fil avant sa fin naturelle. Jthread a une méthode qui peut renvoyer l'objet stop_source.

Donc, il peut être préférable de demander si un fil peut être arrêté avant d'arrêter le fil. Le programme suivant illustre ceci:

#inclure
#inclure
Utilisation de Namespace Std;
void fn ()
couter <<"first code segment of thread" <couter <<"second code segment of thread" <
int main()

Jthread thr (fn);
stop_source ss = thr.get_stop_source ();
si (ss.stop_posible ())
thr.request_stop ();
autre
couter <<"Thread could be stopped!" <thr.rejoindre();
retour 0;

Le segment de code d'arrêt a été placé avant l'instruction JOIN.

La demande d'arrêt a-t-elle été faite?

S'il est possible d'arrêter un fil, cela ne garantit toujours pas qu'une instruction request_stop () réussira à arrêter le fil avant sa fin naturelle. Si le thread ne s'est pas arrêté avant sa fin naturelle comme espéré, alors le programmeur peut vouloir savoir si le fil avait été invité à s'arrêter avec la déclaration de demande_stop ().

L'objet stop_token a la fonction membre,

bool stop_request ()

Cette fonction renvoie vrai si une demande d'arrêt a été faite et fausse autrement. L'objet Jthread peut renvoyer un objet stop_token, avec sa fonction membre,

stop_token get_stop_token () const

Le code de fonction Main () suivant illustre comment savoir si une demande_stop a été publiée:

int main()

Jthread thr (fn);
stop_source ss = thr.get_stop_source ();
si (ss.stop_posible ())
thr.request_stop ();
autre
couter <<"Thread could be stopped!" <stop_token st = thr.get_stop_token ();
si (st.stop_request ())
couter <<"Still waiting for thrread to stop." <autre
thr.request_stop ();
thr.rejoindre();
retour 0;

Tout le code d'arrêt est avant l'instruction JOIN. Ne confondez pas entre les fonctions request_stop () et stop_request ().

Conclusion

Un fil peut être tué de manière responsable avec C ++ 20 et plus. Cela signifie arrêter le fil avec les ressources du fil, libéré. La bibliothèque de thread a les classes stop_token, stop_source, stop_callback et jthread pour tuer un thread responsable. Pour utiliser les objets instantanés stop_token, stop_source et stop_callback, créez le thread avec la classe jthread. La classe Jthread est dans la bibliothèque de threads, qui doit être incluse dans le programme C ++.

La classe Jthread a des fonctions membres pour retourner les objets stop_token et stop_source. La classe JThread elle-même a la fonction membre, request_stop (), pour arrêter un thread. Cette demande est susceptible d'être accordée, mais rien ne garantit qu'il sera accordé. Si la demande est accordée, le fil s'arrête le plus tôt possible, sans atteindre sa fin naturelle, tout est égal.

L'objet stop_source peut être utilisé pour savoir si l'arrêt d'un fil est possible. L'objet stop_token peut être utilisé pour savoir si une demande_stop () a été émise. Une fois la demande d'arrêt faite, elle ne peut pas être retirée (une demande d'arrêt ultérieure n'a aucun effet).