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
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:
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).