Настройка
Я написал довольно сложную часть программного обеспечения на Python (на ПК с ОС Windows). Мое программное обеспечение запускает в основном две оболочки интерпретатора Python. Первая оболочка запускается (я полагаю), когда вы дважды щелкаете по файлу main.py
. Внутри этой оболочки другие потоки запускаются следующим образом:
# 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()
Main_thread
запускает a TCP_thread
и a UDP_thread
. Хотя это отдельные потоки, они все работают в одной оболочке Python.
Main_thread
также запускает подпроцесс. Это делается следующим образом:
p = subprocess.Popen(['python', mySubprocessPath], shell=True)
Из документации Python я понимаю, что этот подпроцесс работает одновременно (!) в отдельном сеансе/оболочке интерпретатора Python. Main_thread
в этом подпроцессе полностью посвящен моему графическому интерфейсу. GUI запускает TCP_thread
для всех своих сообщений.
Я знаю, что все становится немного сложнее. Поэтому я обобщил всю настройку на этом рисунке:
У меня есть несколько вопросов относительно этой настройки. Я перечислил их здесь:
Вопрос 1 [разрешен]
Правда ли, что интерпретатор Python использует только одно ядро процессора за раз, чтобы запустить все потоки? Другими словами, будет ли Python interpreter session 1
(из рисунка) запускать все 3 потока (Main_thread
, TCP_thread
и UDP_thread
) на одном ядре ЦП?
Ответ: да, это правда. GIL (Global Interpreter Lock) гарантирует, что все потоки будут работать на одном ядре процессора за раз.
Вопрос 2 [еще не решен]
У меня есть способ отслеживать, какое ядро ЦП оно?
Вопрос 3 [Частично решена]
Для этого вопроса мы забываем о потоках, но мы фокусируемся на механизме подпроцесса в Python. Запуск нового подпроцесса подразумевает запуск нового интерпретатора Python экземпляра. Правильно ли это?
Ответ: Да, это правильно. Сначала возникла некоторая путаница в отношении того, будет ли следующий код создавать новый экземпляр интерпретатора Python:
p = subprocess.Popen(['python', mySubprocessPath], shell = True)
Вопрос выяснен. Этот код действительно запускает новый экземпляр интерпретатора Python.
Будет ли Python достаточно умен, чтобы отдельный экземпляр интерпретатора Python запускался на другом ядре процессора? Есть ли способ отслеживать, какой из них, возможно, с некоторыми спорадическими заявлениями печати?
Вопрос 4 [Новый вопрос]
Дискуссия в сообществе подняла новый вопрос. По-видимому, существует два подхода при создании нового процесса (в новом экземпляре интерпретатора 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,))
Второй подход имеет очевидный недостаток, что он нацелен только на функцию, тогда как мне нужно открыть новый Python script. Во всяком случае, оба подхода похожи на то, что они достигают?