Mam problem z metodą podprocesową.Popen Pythona.Dlaczego podprocesPopen nie czeka, aż proces potomny zostanie zakończony?
Oto skrypt testowy, który demonstruje problem. Jest uruchamiany na Linuksie.
#!/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)
Zazwyczaj wyjście z tego skryptu jest:
success: 100000
ale czasami jest to
failure: 0
after sleeping the count is 100000
Należy pamiętać, że w przypadku awarii, wybierz natychmiast po wkładce pokazuje 0 wierszy, ale po spanie przez 5 sekund na sekundę wybierz poprawnie pokazuje liczbę wierszy 100000. Mój wniosek jest taki, że jedna z poniższych jest prawdziwa:
- subprocess.Popen nie czeka na wątku potomnego - Wydaje się to sprzeczne z dokumentacją
- wkładka mysql nie jest atomowy - moje rozumienie mysql wydaje się wskazywać Wkładka jest atomowy
- select nie jest zobaczenie właściwego wiersza od razu - według znajomego, który zna mysql lepiej niż ja to robię, nie powinno się zdarzyć ani jedno, ani drugie:
Czego mi brakuje?
FYI, jestem świadomy, że jest to hackowaty sposób interakcji z mysql z Pythona, a MySQLdb prawdopodobnie nie będzie miał tego problemu, ale jestem ciekaw, dlaczego ta metoda nie działa.
Dzięki wszystkim za wielkie odpowiedzi. Patrząc ponownie na dokumentację podprocesu, widzę, że zostałem zignorowany komentarzem "Czekaj na polecenie do wypełnienia", który pojawia się w sekcjach metod dogodności, a nie w sekcji Metody Popena. Dałem ukłon w stronę odpowiedzi Jeda, ponieważ najlepiej odpowiadało na moje pierwotne pytanie, chociaż myślę, że wykorzystam rozwiązanie Paula do moich przyszłych potrzeb w zakresie pisania skryptów. –
Należy pamiętać, że os.system (chyba że zrobisz coś innego) zwróci WARTOŚĆ ZWRACANA procesu (zwykle 0 lub 1). Nie pozwól, żeby cię to ugryzło. –