0

J'essaye de lancer une fonction dans un nouveau thread parce que la fonction fait quelque chose qui n'est pas lié au programme principal.Comment lancer une fonction dans un nouveau thread sans bloquer le programme principal en python?

J'ai essayé de le faire avec le module multiprocesseur:

import multiprocessing 
import time 

def mp_worker(a): 
    #time.sleep(a) 
    print('a:' +str(a)) 
    return 



for k in range(5): 
    p = multiprocessing.Process(target= mp_worker , args=(k,)) 
    p.start() 
    print('keep going :' + str(k)) 

Mais j'ai un tas d'erreur:

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 106, in spawn_main 
    exitcode = _main(fd) 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 115, in _main 
prepare(preparation_data) 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 226, in prepare 
_fixup_main_from_path(data['init_main_from_path']) 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 278, in _fixup_main_from_path 
run_name="__mp_main__") 
    File "C:\Anaconda3\lib\runpy.py", line 254, in run_path 
pkg_name=pkg_name, script_name=fname) 
    File "C:\Anaconda3\lib\runpy.py", line 96, in _run_module_code 
mod_name, mod_spec, pkg_name, script_name) 
    File "C:\Anaconda3\lib\runpy.py", line 85, in _run_code 
exec(code, run_globals) 
    File "C:\Users\Maxime\PycharmProjects\NeuralMassModelSofware_Pyqt5\dj.py", line 14, in <module> 
p.start() 
    File "C:\Anaconda3\lib\multiprocessing\process.py", line 105, in start 
self._popen = self._Popen(self) 
    File "C:\Anaconda3\lib\multiprocessing\context.py", line 212, in _Popen 
return _default_context.get_context().Process._Popen(process_obj) 
    File "C:\Anaconda3\lib\multiprocessing\context.py", line 313, in _Popen 
return Popen(process_obj) 
    File "C:\Anaconda3\lib\multiprocessing\popen_spawn_win32.py", line 34, in __init__ 
    prep_data = spawn.get_preparation_data(process_obj._name) 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 144, in get_preparation_data 
_check_not_importing_main() 
    File "C:\Anaconda3\lib\multiprocessing\spawn.py", line 137, in _check_not_importing_main 
is not going to be frozen to produce an executable.''') 
RuntimeError: 
     An attempt has been made to start a new process before the 
    current process has finished its bootstrapping phase. 

     This probably means that you are not using fork to start your 
    child processes and you have forgotten to use the proper idiom 
    in the main module: 

     if __name__ == '__main__': 
      freeze_support() 
      ... 

    The "freeze_support()" line can be omitted if the program 
    is not going to be frozen to produce an executable. 

Quelqu'un sait comment je peux lancer quelque fonction que je veux dans un nouveau fil et être sûr que le programme principal fonctionne toujours normalement? Je suis un peu perdu avec le multitraitement, j'avoue que :) Je vise à lancer des affichages (graphiques ou imprimés que je ne connais pas encore) pour l'utilisateur dans de nouveaux threads sans interrompre le programme principal.

Répondre

1

Ce que vous faites est pas multithreading, il est muliprocessing.
Modifier.

multiprocessing.Process(... 

avec.

threading.Thread(... 

Python »3.6.1 Documentation: threading.Thread
SO Q & A: multiprocessing-vs-threading-python

A côté de cela, vous pouvez surmonter l'erreur après l'ajout d'un time.sleep(0.2)start(...

+0

Merci pour votre réponse, mais il soulève une erreur: AttributeError: module 'multiprocessing' n'a pas d'attribut 'Thread' – ymmx

+0

@ymmx: Désolé, devrait lire 'threading.Thread (...' – stovfl

+0

Merci qui fonctionne maintenant. Un peu confus cependant, quelle est la différence majeure entre ces deux modules: ils semblent si proches l'un de l'autre. – ymmx

0

C'est ce que je reçois lorsque vous exécutez le code que vous avez fourni:

python3.6 -u "multiprocessingError_Cg.py" 
keep going :0 
a:0 
keep going :1 
keep going :2 
a:1 
a:2 
keep going :3 
keep going :4 
a:3 
a:4 
>Exit code: 0 

Donc, la réponse à votre question est que vous devez rechercher la cause du problème avec multitraitement ailleurs, mais pas la section de code listée dans votre question.

Regardez de plus près ce qui a été fourni dans les réponses et les commentaires here - peut-être que cela pourrait aussi aider dans votre cas?

Voici ce qui a été dit dans les commentaires à l'une des réponses là-bas:

Dave: Would this work if beBusyFor (in your case mp_worker) uses multiprocessing internally?

@Dave just try it out and report back here if it worked. Haven't tested such a case yet, so my opinion that it should work leaving some mess of processes with no parents doesn't matter here and therefore shouldn't be taken in consideration.

Dave: **No cigar ending child processes unfortunately** :(

+0

Merci pour votre réponse. J'ai python3.5. Pensez-vous que je dois mettre à jour le paquet python et multiprocessing pour faire face à mon problème? Je ne comprends toujours pas pourquoi cela arrive !! – ymmx