Introduction détaillée au positionnement et à la destruction dans les threads Python (avec exemples)

不言
Libérer: 2019-02-20 14:41:52
avant
2418 Les gens l'ont consulté

Cet article vous apporte une introduction détaillée au positionnement et à la destruction dans les threads Python (avec des exemples). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Je sentais que quelque chose n'allait pas avant le début du travail et j'avais l'impression que j'allais en assumer la responsabilité. Non, c’est le troisième jour de travail qui me fait culpabiliser.

Nous avons un programme d'arrière-plan incroyable qui peut charger dynamiquement des modules et les exécuter de manière threadée. De cette manière, les fonctions du plug-in sont réalisées. Lorsque le module est mis à jour, le programme en arrière-plan lui-même ne se fermera pas. Il fermera uniquement le thread correspondant au module, mettra à jour le code puis le démarrera.

J'ai donc écrit un module pour montrer mes compétences, mais j'ai oublié d'écrire la fonction de sortie, ce qui entraînait la création d'un nouveau thread à chaque fois que le module était mis à jour. À moins que le programme ne soit redémarré, ces threads seraient créés. rester en vie.

Ce n'est pas possible. Il faut trouver un moyen de le nettoyer, sinon j'ai peur qu'il explose.

Alors comment le nettoyer ? Tout ce à quoi je pense, c'est deux étapes :

  1. Découvrez le numéro de fil qui doit être nettoyé

  2. Détruisez-les ; 🎜>

Découvrez l'ID du fil

Semblable au dépannage habituel, vérifiez d'abord l'état du fil du processus cible via la commande ps, car le nom du fil a été défini par setName, donc normalement je devrais voir le fil de discussion correspondant. Utilisez directement le code suivant pour simuler ce thread :

Version Python du multi-threading

#coding: utf8
import threading
import os
import time

def tt():
    info = threading.currentThread()
    while True:
        print 'pid: ', os.getpid()
        print info.name, info.ident
        time.sleep(3)

t1 = threading.Thread(target=tt)
t1.setName('OOOOOPPPPP')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('EEEEEEEEE')
t2.setDaemon(True)
t2.start()


t1.join()
t2.join()
Copier après la connexion
Copier après la connexion
Sortie :

root@10-46-33-56:~# python t.py
pid:  5613
OOOOOPPPPP 139693508122368
pid:  5613
EEEEEEEEE 139693497632512
...
Copier après la connexion
Copier après la connexion
Vous pouvez voir la sortie du nom du thread dans Python C'est exactement comme ce qu'on a mis en place, mais le résultat de Ps me fait douter de la vie :

root@10-46-33-56:~# ps -Tp 5613
  PID  SPID TTY          TIME CMD
 5613  5613 pts/2    00:00:00 python
 5613  5614 pts/2    00:00:00 python
 5613  5615 pts/2    00:00:00 python
Copier après la connexion
Copier après la connexion
Normalement, ça ne devrait pas être comme ça, je suis un peu confus. Est-ce que je me souviens mal de tout. le long de? Utilisez une autre version linguistique du multi-threading pour tester :

Version C du multi-threading

#include<stdio.h>
#include<sys>
#include<sys>
#include<pthread.h>

void *test(void *name)
{    
    pid_t pid, tid;
    pid = getpid();
    tid = syscall(__NR_gettid);
    char *tname = (char *)name;
    
    // 设置线程名字
    prctl(PR_SET_NAME, tname);
    
    while(1)
    {
        printf("pid: %d, thread_id: %u, t_name: %s\n", pid, tid, tname);
        sleep(3);
    }
}

int main()
{
    pthread_t t1, t2;
    void *ret;
    pthread_create(&t1, NULL, test,  (void *)"Love_test_1");
    pthread_create(&t2, NULL, test,  (void *)"Love_test_2");
    pthread_join(t1, &ret);
    pthread_join(t2, &ret);
}</pthread.h></sys></sys></stdio.h>
Copier après la connexion
Copier après la connexion
Sortie :

root@10-46-33-56:~# gcc t.c -lpthread && ./a.out
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
pid: 5575, thread_id: 5577, t_name: Love_test_2
pid: 5575, thread_id: 5576, t_name: Love_test_1
...
Copier après la connexion
Copier après la connexion
Vérifiez à nouveau avec la commande PS :

root@10-46-33-56:~# ps -Tp 5575
  PID  SPID TTY          TIME CMD
 5575  5575 pts/2    00:00:00 a.out
 5575  5576 pts/2    00:00:00 Love_test_1
 5575  5577 pts/2    00:00:00 Love_test_2
Copier après la connexion
Copier après la connexion
C'est exact, le nom du fil est effectivement visible via PS !

Mais pourquoi ne puis-je pas voir celui de Python ? Puisque le nom du fil est défini via

, jetons un coup d'œil à la définition : setName

[threading.py]
class Thread(_Verbose):
    ...
    @property
    def name(self):
        """A string used for identification purposes only.

        It has no semantics. Multiple threads may be given the same name. The
        initial name is set by the constructor.

        """
        assert self.__initialized, "Thread.__init__() not called"
        return self.__name

    @name.setter
    def name(self, name):
        assert self.__initialized, "Thread.__init__() not called"
        self.__name = str(name)
        
    def setName(self, name):
        self.name = name
    ...
Copier après la connexion
Copier après la connexion
Ce que vous voyez ici définit simplement les propriétés de l'objet

, et il n'a pas touché les fondamentaux. Ensuite, je ne peux absolument pas le voir ~Thread

Il semble que nous ne puissions plus rechercher les noms de threads python en externe par des moyens tels que

ou ps, nous ne pouvons donc le résoudre qu'à l'intérieur. Python. /proc/

La question devient donc : comment obtenir tous les threads en cours d'exécution dans Python ?

peut parfaitement résoudre ce problème ! Pourquoi ?threading.enumerate

Parce qu'il est clairement indiqué dans la documentation de la fonction ci-dessous, renvoyant tous les

objets thread actifs, à l'exclusion de ceux terminés et non démarrés.

[threading.py]

def enumerate():
    """Return a list of all Thread objects currently alive.

    The list includes daemonic threads, dummy thread objects created by
    current_thread(), and the main thread. It excludes terminated threads and
    threads that have not yet been started.

    """
    with _active_limbo_lock:
        return _active.values() + _limbo.values()
Copier après la connexion
Copier après la connexion
Parce que nous obtenons l'objet Thread, nous pouvons obtenir les informations relatives au fil de discussion grâce à cela !

Veuillez consulter l'exemple de code complet :

#coding: utf8

import threading
import os
import time


def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident
        print
        time.sleep(1)
        
def tt():
    info = threading.currentThread()
    pid = os.getpid()
    while True:
        print 'pid: {}, tid: {}, tname: {}'.format(pid, info.name, info.ident)
        time.sleep(3)
        return

t1 = threading.Thread(target=tt)
t1.setName('Thread-test1')
t1.setDaemon(True)
t1.start()

t2 = threading.Thread(target=tt)
t2.setName('Thread-test2')
t2.setDaemon(True)
t2.start()

t3 = threading.Thread(target=get_thread)
t3.setName('Checker')
t3.setDaemon(True)
t3.start()

t1.join()
t2.join()
t3.join()
Copier après la connexion
Copier après la connexion
Sortie :

root@10-46-33-56:~# python t_show.py
pid: 6258, tid: Thread-test1, tname: 139907597162240
pid: 6258, tid: Thread-test2, tname: 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Thread-test1 139907597162240
Checker 139907576182528
Thread-test2 139907586672384

------- Running threads On Pid: 6258 -------
MainThread 139907616806656
Checker 139907576182528
...
Copier après la connexion
Copier après la connexion
Le code semble un peu long, mais la logique est assez simple,

et Thread-test1 Ils affichent tous le pid actuel, l'identifiant du thread et le nom du thread, puis quittent après 3 secondes. Il s'agit de simuler la sortie normale du thread. Thread-test2

Et le thread

génère tous les threads actifs du processus en cours jusqu'à Checker chaque seconde. threading.enumerate

On voit clairement que les informations de

et Thread-test1 sont visibles au début. Lorsqu'ils sortent, il ne reste que Thread-test2 et MainThread eux-mêmes. Checker

Détruisez le fil spécifié

Maintenant que nous pouvons obtenir le nom et l'identifiant du fil, nous pouvons également tuer le fil spécifié !

Supposons maintenant que

soit devenu noir et fou, et que nous devions l'arrêter, alors nous pouvons le résoudre de cette façon : Thread-test2

Sur la base du code ci-dessus, ajoutez et complétez Le code suivant :

def _async_raise(tid, exctype):
    """raises the exception, performs cleanup if needed"""
    tid = ctypes.c_long(tid)
    if not inspect.isclass(exctype):
        exctype = type(exctype)
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

def stop_thread(thread):
    _async_raise(thread.ident, SystemExit)

def get_thread():
    pid = os.getpid()
    while True:
        ts = threading.enumerate()
        print '------- Running threads On Pid: %d -------' % pid
        for t in ts:
            print t.name, t.ident, t.is_alive()
            if t.name == 'Thread-test2':
                print 'I am go dying! Please take care of yourself and drink more hot water!'
                stop_thread(t)
        print
        time.sleep(1)
Copier après la connexion
sort

root@10-46-33-56:~# python t_show.py
pid: 6362, tid: 139901682108160, tname: Thread-test1
pid: 6362, tid: 139901671618304, tname: Thread-test2
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
Thread-test2 139901671618304 True
Thread-test2: I am go dying. Please take care of yourself and drink more hot water!

pid: 6362, tid: 139901682108160, tname: Thread-test1
------- Running threads On Pid: 6362 -------
MainThread 139901706389248 True
Thread-test1 139901682108160 True
Checker 139901661128448 True
// Thread-test2 已经不在了
Copier après la connexion
Après une opération, même si nous traitons

comme ça, il se soucie toujours de nous : Thread-test2 Boire plus d'eau chaude ,

PS : Bien que l'eau chaude soit bonne, huit tasses suffisent, alors ne soyez pas gourmand.

Revenons à l'histoire principale, la méthode ci-dessus est extrêmement grossière. Pourquoi dites-vous cela ?

Parce que son principe est le suivant : utiliser l'API intégrée de Python pour déclencher une exception sur le thread spécifié, lui permettant de se fermer automatiquement

Introduction détaillée au positionnement et à la destruction dans les threads Python (avec exemples) ;

N'utilisez pas cette méthode en dernier recours, car il existe une certaine probabilité de déclencher des problèmes indescriptibles. Souviens-toi! Ne me demandez pas pourquoi je sais...

Pourquoi est-il si difficile d'arrêter un thread ?

Le multithread lui-même est conçu pour la concurrence collaborative dans le cadre du processus. unité de planification. Les threads partagent les ressources, il y aura donc de nombreux mécanismes de verrouillage et contrôles d’état.

Si vous utilisez la force pour tuer des threads, il y a de fortes chances que des bugs inattendus se produisent. Et la libération la plus importante des ressources de verrouillage peut également provoquer des problèmes inattendus.

Nous ne pouvons même pas tuer les threads directement comme tuer des processus via des signaux, car kill ne peut répondre à nos attentes qu'en traitant des processus, mais il n'est évidemment pas possible de traiter les threads, quel que soit le thread qui est tué, l'ensemble du processus. va sortir!

Et à cause du GIL, de nombreux enfants pensent que les threads de Python sont implémentés par Python lui-même et n'existent pas réellement. Python devrait pouvoir les détruire directement, n'est-ce pas ?

Cependant, en fait, les threads de Python sont de vrais threads !

Qu'est-ce que cela signifie ? Les threads Python sont des threads natifs créés par le système d'exploitation via pthread. Python utilise uniquement GIL pour contraindre ces threads afin de décider quand commencer la planification. Par exemple, après avoir exécuté un certain nombre d'instructions, le GIL sera remis. Quant à savoir qui remportera l'oiran, cela dépend du système d'exploitation.

S'il s'agit d'un simple fil de discussion, le système dispose en fait d'un moyen d'y mettre fin, tel que : pthread_exit, pthread_kill ou pthread_cancel Pour plus de détails, veuillez consulter : https://www. cnblogs.com/Creat ..

Quel dommage : Il n'y a pas d'encapsulation de ces méthodes au niveau Python ! Oh mon Dieu, tellement en colère ! Peut-être que les gens pensent que les fils doivent être traités avec douceur.

Comment quitter un fil de discussion en douceur

Si vous voulez quitter un fil de discussion en douceur, c'est presque un non-sens~

Soit quitter après l'exécution, soit définir le bit d'indicateur, et vérifiez fréquemment le bit d'indicateur. Si vous devez quitter, quittez simplement.

Extension

"Comment terminer correctement un thread enfant en cours d'exécution" : https://www.cnblogs.com/Creat...
"Ne détruisez pas grossièrement les threads python" :http://xiaorui.cc/2017/02/22/...

Bienvenue à tous les experts pour donner des conseils et échanger, groupe de discussion QQ : 258498217
Veuillez noter la réimpression de la source Ming : https://segmentfault.com/a/11...







c

linux
  •                                                                                               266 lectures                                                              Il faut 30 minutes pour lire                                                                                                                                     



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    ContexteAvant de commencer le travail, je sentais que quelque chose n'allait pas et j'avais l'impression que j'allais en prendre la responsabilité. Non, c’est le troisième jour de travail qui me fait culpabiliser. Nous avons un programme d'arrière-plan incroyable qui peut charger dynamiquement des modules et les exécuter dans des threads. De cette manière, les fonctions du plug-in peuvent être réalisées. Lorsque le module est mis à jour, le programme en arrière-plan lui-même ne se fermera pas. Il fermera uniquement le thread correspondant au module, mettra à jour le code puis le démarrera. J'ai donc écrit un module pour montrer mes compétences, mais j'ai oublié d'écrire la fonction de sortie, ce qui a entraîné la création d'un nouveau thread à chaque fois que le module était mis à jour. À moins que le programme ne soit redémarré, ces threads seraient créés. rester en vie. Ce n'est pas possible. Il faut trouver un moyen de le nettoyer, sinon j'ai peur qu'il explose. Alors comment le nettoyer ? Tout ce à quoi je pense, c'est deux étapes :

    Découvrez le numéro de fil qui doit être nettoyé

    Détruisez-les ; 🎜>

    Découvrez l'ID du fil

    Semblable au dépannage habituel, vérifiez d'abord l'état du fil du processus cible via la commande ps, car le nom du fil a été défini par setName, donc normalement je devrais voir le fil de discussion correspondant. Utilisez directement le code suivant pour simuler ce fil :

    Version Python du multi-threading

      Sortie :
    1. Vous pouvez voir la sortie du nom du fil dans Python C'est exactement comme ce qu'on a mis en place, mais le résultat de Ps me fait douter de la vie :
    2. Normalement, ça ne devrait pas être comme ça, je suis un peu confus. Est-ce que je me souviens mal de tout. le long de? Utilisez une autre version linguistique du multi-threading pour tester :

    3. Version C du multi-threading

    Sortie :

    Vérifiez à nouveau avec la commande PS :

    #coding: utf8
    import threading
    import os
    import time
    
    def tt():
        info = threading.currentThread()
        while True:
            print 'pid: ', os.getpid()
            print info.name, info.ident
            time.sleep(3)
    
    t1 = threading.Thread(target=tt)
    t1.setName('OOOOOPPPPP')
    t1.setDaemon(True)
    t1.start()
    
    t2 = threading.Thread(target=tt)
    t2.setName('EEEEEEEEE')
    t2.setDaemon(True)
    t2.start()
    
    
    t1.join()
    t2.join()
    Copier après la connexion
    Copier après la connexion

    C'est exact, le nom du fil est effectivement visible via PS !

    root@10-46-33-56:~# python t.py
    pid:  5613
    OOOOOPPPPP 139693508122368
    pid:  5613
    EEEEEEEEE 139693497632512
    ...
    Copier après la connexion
    Copier après la connexion
    Mais pourquoi ne puis-je pas voir celui de Python ? Puisque le nom du fil est défini via

    , jetons un coup d'œil à la définition :

    root@10-46-33-56:~# ps -Tp 5613
      PID  SPID TTY          TIME CMD
     5613  5613 pts/2    00:00:00 python
     5613  5614 pts/2    00:00:00 python
     5613  5615 pts/2    00:00:00 python
    Copier après la connexion
    Copier après la connexion

    Ce que vous voyez ici définit simplement les propriétés de l'objet

    , et il n'a pas touché les fondamentaux. Ensuite, je ne peux absolument pas le voir ~

    Il semble que nous ne puissions plus rechercher les noms de threads python en externe par des moyens tels que
    #include<stdio.h>
    #include<sys>
    #include<sys>
    #include<pthread.h>
    
    void *test(void *name)
    {    
        pid_t pid, tid;
        pid = getpid();
        tid = syscall(__NR_gettid);
        char *tname = (char *)name;
        
        // 设置线程名字
        prctl(PR_SET_NAME, tname);
        
        while(1)
        {
            printf("pid: %d, thread_id: %u, t_name: %s\n", pid, tid, tname);
            sleep(3);
        }
    }
    
    int main()
    {
        pthread_t t1, t2;
        void *ret;
        pthread_create(&t1, NULL, test,  (void *)"Love_test_1");
        pthread_create(&t2, NULL, test,  (void *)"Love_test_2");
        pthread_join(t1, &ret);
        pthread_join(t2, &ret);
    }</pthread.h></sys></sys></stdio.h>
    Copier après la connexion
    Copier après la connexion
    ou

    , nous ne pouvons donc le résoudre qu'à l'intérieur. Python.

    root@10-46-33-56:~# gcc t.c -lpthread && ./a.out
    pid: 5575, thread_id: 5577, t_name: Love_test_2
    pid: 5575, thread_id: 5576, t_name: Love_test_1
    pid: 5575, thread_id: 5577, t_name: Love_test_2
    pid: 5575, thread_id: 5576, t_name: Love_test_1
    ...
    Copier après la connexion
    Copier après la connexion
    La question devient donc : comment obtenir tous les threads en cours d'exécution dans Python ?

    root@10-46-33-56:~# ps -Tp 5575
      PID  SPID TTY          TIME CMD
     5575  5575 pts/2    00:00:00 a.out
     5575  5576 pts/2    00:00:00 Love_test_1
     5575  5577 pts/2    00:00:00 Love_test_2
    Copier après la connexion
    Copier après la connexion
    peut parfaitement résoudre ce problème ! Pourquoi ?

    Parce qu'il est clairement indiqué dans la documentation de la fonction ci-dessous, renvoyant tous les

    objets threadsetName actifs, à l'exclusion de ceux terminés et non démarrés.

    [threading.py]
    class Thread(_Verbose):
        ...
        @property
        def name(self):
            """A string used for identification purposes only.
    
            It has no semantics. Multiple threads may be given the same name. The
            initial name is set by the constructor.
    
            """
            assert self.__initialized, "Thread.__init__() not called"
            return self.__name
    
        @name.setter
        def name(self, name):
            assert self.__initialized, "Thread.__init__() not called"
            self.__name = str(name)
            
        def setName(self, name):
            self.name = name
        ...
    Copier après la connexion
    Copier après la connexion

    Parce que nous obtenons l'objet Thread, nous pouvons obtenir les informations liées au fil de discussion grâce à cela ! Thread

    Veuillez consulter l'exemple de code complet :

    ps/proc/Sortie :

    Le code semble un peu long, mais la logique est assez simple,

    et threading.enumerate Ils affichent tous le pid actuel, l'identifiant du thread et le nom du thread, puis quittent après 3 secondes. Il s'agit de simuler la sortie normale du thread.

    Et le thread génère tous les threads actifs du processus en cours jusqu'à chaque seconde.

    [threading.py]
    
    def enumerate():
        """Return a list of all Thread objects currently alive.
    
        The list includes daemonic threads, dummy thread objects created by
        current_thread(), and the main thread. It excludes terminated threads and
        threads that have not yet been started.
    
        """
        with _active_limbo_lock:
            return _active.values() + _limbo.values()
    Copier après la connexion
    Copier après la connexion
    On voit clairement que les informations de

    et

    sont visibles au début. Lorsqu'ils sortent, il ne reste que

    et

    eux-mêmes.
    #coding: utf8
    
    import threading
    import os
    import time
    
    
    def get_thread():
        pid = os.getpid()
        while True:
            ts = threading.enumerate()
            print '------- Running threads On Pid: %d -------' % pid
            for t in ts:
                print t.name, t.ident
            print
            time.sleep(1)
            
    def tt():
        info = threading.currentThread()
        pid = os.getpid()
        while True:
            print 'pid: {}, tid: {}, tname: {}'.format(pid, info.name, info.ident)
            time.sleep(3)
            return
    
    t1 = threading.Thread(target=tt)
    t1.setName('Thread-test1')
    t1.setDaemon(True)
    t1.start()
    
    t2 = threading.Thread(target=tt)
    t2.setName('Thread-test2')
    t2.setDaemon(True)
    t2.start()
    
    t3 = threading.Thread(target=get_thread)
    t3.setName('Checker')
    t3.setDaemon(True)
    t3.start()
    
    t1.join()
    t2.join()
    t3.join()
    Copier après la connexion
    Copier après la connexion

    Détruisez le fil spécifié

    root@10-46-33-56:~# python t_show.py
    pid: 6258, tid: Thread-test1, tname: 139907597162240
    pid: 6258, tid: Thread-test2, tname: 139907586672384
    
    ------- Running threads On Pid: 6258 -------
    MainThread 139907616806656
    Thread-test1 139907597162240
    Checker 139907576182528
    Thread-test2 139907586672384
    
    ------- Running threads On Pid: 6258 -------
    MainThread 139907616806656
    Thread-test1 139907597162240
    Checker 139907576182528
    Thread-test2 139907586672384
    
    ------- Running threads On Pid: 6258 -------
    MainThread 139907616806656
    Thread-test1 139907597162240
    Checker 139907576182528
    Thread-test2 139907586672384
    
    ------- Running threads On Pid: 6258 -------
    MainThread 139907616806656
    Checker 139907576182528
    ...
    Copier après la connexion
    Copier après la connexion
    Maintenant que nous pouvons obtenir le nom et l'identifiant du fil, nous pouvons également tuer le fil spécifié !

    Thread-test1Supposons maintenant que Thread-test2 soit devenu noir et fou, et que nous devions l'arrêter, alors nous pouvons le résoudre de cette façon :

    Sur la base du code ci-dessus, ajoutez et complétez Le code suivant : Checkerthreading.enumerate

    sort

    Thread-test1Thread-test2 Après une opération, même si nous traitons MainThread comme ça, il se soucie toujours de nous : Checker Boire plus d'eau chaude

    ,

    PS : Bien que l'eau chaude soit bonne, huit tasses suffisent, alors ne soyez pas gourmand.

    Retour à l'histoire principale, la méthode ci-dessus est extrêmement grossière. Pourquoi dites-vous cela ?

    Parce que son principe est le suivant : utiliser l'API intégrée de Python pour déclencher une exception sur le thread spécifié, lui permettant de se fermer automatiquement

    Introduction détaillée au positionnement et à la destruction dans les threads Python (avec exemples)

    ;

    N'utilisez pas cette méthode en dernier recours, car il existe une certaine probabilité de déclencher des problèmes indescriptibles. Souviens-toi! Ne me demandez pas pourquoi je sais...

    Pourquoi est-il si difficile d'arrêter un thread ?

    Le multithread lui-même est conçu pour la concurrence collaborative dans le cadre du processus. unité de planification. Les threads partagent les ressources, il y aura donc de nombreux mécanismes de verrouillage et contrôles d’état.

    Si vous utilisez la force pour tuer des threads, il y a de fortes chances que des bugs inattendus se produisent. Et la libération la plus importante des ressources de verrouillage peut également provoquer des problèmes inattendus.

    Nous ne pouvons même pas tuer le thread directement comme tuer le processus via un signal, car kill ne peut répondre à nos attentes qu'en traitant des processus, mais il n'est évidemment pas possible de traiter les threads, quel que soit le thread. est tué, tout le processus se terminera !

    Et à cause du GIL, de nombreux enfants pensent que les threads de Python sont implémentés par Python lui-même et n'existent pas réellement. Python devrait pouvoir les détruire directement, n'est-ce pas ?

    Cependant, en fait, les threads de Python sont de vrais threads !

    Qu'est-ce que cela signifie ? Les threads Python sont des threads natifs créés par le système d'exploitation via pthread. Python utilise uniquement GIL pour contraindre ces threads afin de décider quand commencer la planification. Par exemple, après avoir exécuté un certain nombre d'instructions, le GIL sera remis. Quant à savoir qui remportera l'oiran, cela dépend du système d'exploitation.

    S'il s'agit d'un simple fil de discussion, le système dispose en fait d'un moyen d'y mettre fin, tel que : pthread_exit, pthread_kill ou pthread_cancel Pour plus de détails, veuillez consulter : https://www. cnblogs.com/Creat ..

    Quel dommage : Il n'y a pas d'encapsulation de ces méthodes au niveau Python ! Oh mon Dieu, tellement en colère ! Peut-être que les gens pensent que les fils doivent être traités avec douceur.

    Comment quitter un fil de discussion en douceur

    Si vous voulez quitter un fil de discussion en douceur, c'est presque un non-sens~

    Soit quitter après l'exécution, soit définir le bit d'indicateur, et vérifiez fréquemment le bit d'indicateur. Si vous devez quitter, quittez simplement.

    Extension

    "Comment terminer correctement un thread enfant en cours d'exécution" : https://www.cnblogs.com/Creat...
    "Ne détruisez pas grossièrement les threads python" :http://xiaorui.cc/2017/02/22/...

    Bienvenue à tous les experts pour donner des conseils et échanger, groupe de discussion QQ : 258498217
    Veuillez noter la réimpression de la source Ming : https://segmentfault.com/a/11...

    • Tous droits réservés



    Si vous pensez que mon article vous est utile, n'hésitez pas à le féliciter

    Vous pourriez vous sentir intéressé



    2 commentaires                                                                                                                                                 Tri temporel




            



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

    Si c'était moi qui pouvais tuer -9, je préférerais en tuer mille par erreur plutôt que d'en laisser un partir, palourde

                                                                                                                                                                                                                                                                                                                                                                   Répondre                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                                                                                                                     —                                                                                                                                                                                                                                                                                       auteur                                                                                                                                                                                                                    Ajouter une réponseChargement en cours...Afficher plus de commentaires

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!