La mise en place
J'ai écrit un logiciel assez complexe en Python (sur un PC Windows). Mon logiciel démarre essentiellement deux shells d'interprétation Python. Le premier shell démarre (je suppose) lorsque vous double-cliquez sur le fichier main.py
dossier. Dans ce shell, d'autres threads sont lancés de la manière suivante :
# Start TCP_thread
TCP_thread = threading.Thread(name = 'TCP_loop', target = TCP_loop, args = (TCPsock,))
TCP_thread.start()
# Start UDP_thread
UDP_thread = threading.Thread(name = 'UDP_loop', target = UDP_loop, args = (UDPsock,))
TCP_thread.start()
Le site Main_thread
commence un TCP_thread
et un UDP_thread
. Bien qu'il s'agisse de fils séparés, ils s'exécutent tous dans un seul shell Python.
Le site Main_thread
démarre également un sous-processus. Cela se fait de la manière suivante :
p = subprocess.Popen(['python', mySubprocessPath], shell=True)
D'après la documentation de Python, je comprends que ce sous-processus s'exécute simultanément ( !) dans une session/un shell séparé de l'interpréteur Python. Le site Main_thread
dans ce sous-processus est entièrement dédié à mon interface graphique. L'interface graphique démarre un TCP_thread
pour toutes ses communications.
Je sais que les choses se compliquent un peu. C'est pourquoi j'ai résumé l'ensemble du dispositif dans cette figure :
J'ai plusieurs questions concernant cette installation. Je vais les énumérer ici :
Question 1 [ Résolu ]
Est-il vrai qu'un interpréteur Python n'utilise qu'un seul cœur de CPU à la fois pour exécuter tous les threads ? En d'autres termes, est-ce que le Python interpreter session 1
(de la figure) exécuter les 3 fils ( Main_thread
, TCP_thread
y UDP_thread
) sur un seul cœur de CPU ?
Réponse : oui, c'est vrai. Le GIL (Global Interpreter Lock) garantit que tous les threads fonctionnent sur un seul cœur de processeur à la fois.
Question 2 [ Pas encore résolu ]
Est-ce que j'ai un moyen de savoir de quel cœur de CPU il s'agit ?
Question 3 [ Partiellement résolu ]
Pour cette question, nous oublions fils mais nous nous concentrons sur le sous-processus en Python. Le démarrage d'un nouveau sous-processus implique le démarrage d'un nouvel interpréteur Python instance . Est-ce correct ?
Réponse : Oui, c'est exact. Au début, il y avait une certaine confusion quant à savoir si le code suivant créerait une nouvelle instance de l'interpréteur Python :
p = subprocess.Popen(['python', mySubprocessPath], shell = True)
La question a été clarifiée. Ce code démarre effectivement une nouvelle instance de l'interpréteur Python.
Python sera-t-il assez intelligent pour que cette instance distincte de l'interpréteur Python s'exécute sur un cœur de CPU différent ? Y a-t-il un moyen de savoir lequel, peut-être avec des instructions print sporadiques ?
Question 4 [ Nouvelle question ]
La discussion communautaire a soulevé une nouvelle question. Il existe apparemment deux approches lors du lancement d'un nouveau processus (dans une nouvelle instance de l'interpréteur Python) :
# Approach 1(a)
p = subprocess.Popen(['python', mySubprocessPath], shell = True)
# Approach 1(b) (J.F. Sebastian)
p = subprocess.Popen([sys.executable, mySubprocessPath])
# Approach 2
p = multiprocessing.Process(target=foo, args=(q,))
La deuxième approche présente l'inconvénient évident de ne cibler qu'une fonction - alors que je dois ouvrir un nouveau script Python. Quoi qu'il en soit, les deux approches sont-elles similaires dans ce qu'elles réalisent ?