Вы можете решить эту проблему в Python разными способами.Вот три очевидных:
- Так же, как оболочка решает это.Это, вероятно, самый простой способ, по крайней мере, в Unix-подобной системе, но он обеспечивает некоторое разделение, которое вам может не понадобиться, и не работает в Windows.
- Через опрос.Если вам нечего делать во время опроса, это может быть пустой тратой системных ресурсов.
- Через многопоточность.Это самый легкий вес, но и самый хитрый, чтобы получить право.
Способ, которым оболочка справляется с этим, заключается в том, что:
( sleep 1; echo "one" ) &
разветвляется на подоболочку.Суб-оболочка разветвляется на суб-суб-оболочку, а суб-суб-оболочка exec
s - sleep 1
.Первая вложенная оболочка теперь ожидает вторую вложенную оболочку, а когда она заканчивается, исполняется (на этот раз не требуется разветвление) echo "one"
.(Между тем основная оболочка вообще не ждет.)
Обратите внимание, что число процессов здесь было 3: основная оболочка, суб-оболочка, суб-суб-оболочка, которая стала первым эхом, изатем первый субоболочка стал вторым эхом.Основная оболочка может ожидать и, следовательно, получить статус результата первой вложенной оболочки, но она вообще не может видеть вложенную оболочку.
Чтобы сделать это непосредственно в Python, либо вызовитеоболочка для последовательного запуска двух команд - эта оболочка разветвляется один раз для первой команды, затем запускает вторую напрямую или использует os.fork()
.Если вы - потомок вилки, используйте subprocess
(с .call
или .Popen
или любым другим) для запуска первой команды, затем используйте os.exec
для запуска второй команды.В качестве альтернативы, вы можете добавить еще больше процессов и / или использовать multiprocessing
(который добавляет необычный механизм связи между вашими различными процессами Python, так что вы можете делать гораздо больше полезных вещей, но он еще тяжелее).
Чтобы использовать опрос, обратите внимание, что экземпляр subprocess.Popen
имеет метод poll
.Вызовите это, чтобы узнать, запущен ли процесс или уже завершен.
Чтобы использовать многопоточность, раскрутите потоки, которые вызывают subprocess.Popen
и / или которые вызывают метод .wait
в созданном подпроцессе, а затем вращайтедо следующего в цепи.Вам нужно будет добавить свою собственную блокировку вокруг любых переменных, совместно используемых различными потоками (например, различными рабочими списками) - может иметь смысл разделить их перед тем, как раскрутить потоки, чтобы у каждого потока был собственный рабочий список.и просто вносит окончательные результаты, если таковые имеются, под замком).