2017-09-21 6 views
1

Je suis en cours d'exécution le code suivant:Time.sleep semble bloquer le thread principal, pas seulement le fil de l'enfant?

from threading import Thread 
from time import sleep 

def file_write(file_input, num_lines): 
    sleep(10) 
    file = open("testfile.txt", "w") 
    for line in num_lines: 
     file.write("{}: {}".format(line, file_input)) 

    file.close() 


if __name__ == '__main__': 
    curr_thread = Thread(target=file_write, args=("Norah", range(5))) 
    curr_thread.daemon = False 
    curr_thread.start() 

L'attente est le fil conducteur quitte immédiatement, parce que je ne l'appelle pas se joindre. Mais ce n'est pas le cas. Les appels de sommeil bloquent-ils aussi le thread principal?

EDIT: Il y a une question similaire posée dans ce fil: time.sleep -- sleeps thread or process? mais ce n'est pas la même chose.
J'ai regardé le fil: il dit que le sommeil ne bloque pas les processus fils, mais il ne dit pas ce qu'il advient du fil principal. Lorsque j'ai exécuté le code à partir de la réponse acceptée, le thread principal n'est pas sorti immédiatement, comme je le pensais.

MISE À JOUR: On dirait que multithreading ne résoudra pas mon problème: le but est d'exécuter un tas de tâches en arrière-plan. J'utilise le module de sous-processus à la place maintenant.

+0

Copie possible de [time.sleep - dort thread ou processus?] (Https://stackoverflow.com/questions/92928/time-sleep-sleeps-thread-or-process) –

+0

J'ai regardé le fil: il dit que le sommeil ne provoque pas de blocage des processus enfants, mais il ne dit pas ce qu'il advient du thread principal. Lorsque j'ai exécuté le code à partir de la réponse acceptée, le thread principal n'est pas sorti immédiatement, comme je le pensais. –

+0

Faites-vous 'curr_thread.join()'? Le thread principal devrait quitter immédiatement. Rejoindre le thread attendra jusqu'à ce que le thread est terminé avant de quitter. –

Répondre

1

sommeil appelle le bloc seul le fil dans lequel ils sont appelés. Imprimer n'importe quoi dans le fil principal immédiatement après l'appel à curr_thread.start() vous le prouvera.

Cependant, si vous interrompez votre code (Ctrl-C), vous verrez une trace de la pile utile. Le dernier appel est à l'intérieur du module _shutdown()threading méthode, qui semble attendre tous fils non démon à la fin.

t = _pickSomeNonDaemonThread() 
while t: 
    t.join() 
    t = _pickSomeNonDaemonThread() 

et lecture the documentation pour le module de filetage, vous pouvez voir que: « Le programme Python ensemble sort lorsqu'aucun vivant fils non démon sont à gauche. » Donc, parce que vous avez fait curr_thread.daemon = False, vous forcez le thread principal à attendre que ce thread se termine en premier.

Je tiens à souligner, cependant, que les fils héritent du « démon-ness » de leurs parents. Puisque le thread principal n'est jamais un thread démon, vous pourriez avoir laissé le curr_thread.daemon = False, et vous auriez le même comportement.

+0

Cela est vrai, si je mets curr_thread.daemon = True, alors le programme se termine immédiatement, mais le thread fils semble être démoli dans le processus: les appels d'écriture de fichiers ne s'exécutent pas. –

+0

@NorahBorus Oui, le deuxième thread sera terminé. C'est parce que tout le processus se termine, car il n'y a plus de threads non démon. Le thread principal est le seul thread non démon si vous définissez 'curr_thread.daemon = True', non? Donc, quand il se termine (immédiatement, puisque vous n'avez jamais 'joint()'), tout le processus va se terminer. – bnaecker

+0

@NorahBorus Cela commence à ressembler un peu à un problème XY. Pourquoi voulez-vous créer un deuxième fil du tout? Ou est-ce un exercice pour comprendre le module d'enfilage? – bnaecker

0

Bien sûr, un sommeil dans un thread ne bloque pas le thread principal.

Ce code démontre que le principal continue:

from threading import Thread 
from time import sleep 

def file_write(file_input, num_lines): 
    print('a') 
    sleep(5) 
    print('b') 


if __name__ == '__main__': 
    curr_thread = Thread(target=file_write, args=("Norah", range(5))) 
    curr_thread.daemon = False 
    curr_thread.start() 
    for i in range(5): 
     sleep(1) 
     print(i) 

Sortie:

a 
0 
1 
2 
3 
b 
4 
+0

Voir le commentaire de bnaeckner et mon exemple de code: J'ai spécifié que la question concerne ce qui se passe lorsque le thread principal est en cours de fermeture. –