У меня проблема с подпроцессом Python.Popen.Почему подпроцесс.Popen не ждет завершения дочернего процесса?
Вот тестовый скрипт, который демонстрирует проблему. Он запускается в ящике Linux.
#!/usr/bin/env python
import subprocess
import time
def run(cmd):
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
return p
### START MAIN
# copy some rows from a source table to a destination table
# note that the destination table is empty when this script is run
cmd = 'mysql -u ve --skip-column-names --batch --execute="insert into destination (select * from source limit 100000)" test'
run(cmd)
# check to see how many rows exist in the destination table
cmd = 'mysql -u ve --skip-column-names --batch --execute="select count(*) from destination" test'
process = run(cmd)
count = (int(process.communicate()[0][:-1]))
# if subprocess.Popen() waited for the child to terminate than count should be
# greater than 0
if count > 0:
print "success: " + str(count)
else:
print "failure: " + str(count)
time.sleep(5)
# find out how many rows exists in the destination table after sleeping
process = run(cmd)
count = (int(process.communicate()[0][:-1]))
print "after sleeping the count is " + str(count)
Обычно выход из этого сценария:
success: 100000
но иногда это
failure: 0
after sleeping the count is 100000
Обратите внимание, что в случае отказа, то выберите сразу после вставки показывает 0 строк, но после спать в течение 5 секунд, второй выбор правильно показывает количество строк в 100000. Я пришел к выводу, что одно из следующего верно:
- subprocess.Popen не ждет ребенка нити прекратить - Это, кажется, противоречит в документации по
- для MySQL вставки не является атомарной - мое понимание MySQL, кажется, указывает вставка атомное
- избранных не является видя правильное количество строк сразу же - по словам друга, который знает mysql лучше, чем я, это не должно происходить ни
Что мне не хватает?
FYI, я знаю, что это хакерский способ взаимодействия с mysql из Python и MySQLdb, скорее всего, не будет иметь этой проблемы, но мне любопытно, почему этот метод не работает.
Спасибо всем за отличные ответы. Еще раз взглянув на документацию подпроцесса, я вижу, что я был отброшен комментарием «Дождитесь завершения команды», которое появляется в разделах методов удобства, а не в разделе метода Popen. Я дал кивком ответ Джеда, так как он наилучшим образом ответил на мой первоначальный вопрос, хотя я думаю, что буду использовать решение Павла для моих будущих потребностей в написании сценариев. –
Имейте в виду, что os.system (если вы не делаете что-то еще с ней) возвращает RETURN VALUE процесса (обычно 0 или 1). Не позволяйте этому укусить вас. –