私はPythonのsubprocess.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
時にはそれは、障害の場合には、すぐに挿入後の選択が0の行を示していますが後ということ
failure: 0
after sleeping the count is 100000
注意です5秒間スリープすると、2番目のセレクトで100000という行数が正しく表示されます。私の結論は、次のいずれかが当てはまることです。
- subprocess.Popenが終了する子スレッドを待っていない - これは、MySQLのインサートがアトミックではありません文書
- と矛盾するようだ - mysqlのの私の理解では、インサートを示すように見えるが選択
- アトミックではありませんすぐに正しい行数を見る - 私よりも優れているmysqlを知っている友人によれば、どちらも起こらないはずです
私は何が欠けていますか?
参考までに、これはPythonのmysqlとやりとりするためのハックな方法だと思っていますが、MySQLdbにはこの問題はないようですが、なぜこの方法がうまくいかないのか不思議です。
すてきな答えをお寄せいただきありがとうございます。サブプロセスのドキュメントをもう一度見てみると、Popenメソッドのセクションではなく便利なメソッドのセクションに表示される "コマンドの完了を待つ"というコメントが表示されています。 私は、私のオリジナルの質問に最もよく答えたので、私はJedの答えにうなずきました。私は将来のスクリプト作成のためにPaulのソリューションを使用すると思います。 –
os.system(他の何かをしない限り)は、プロセスの戻り値(通常は0または1)を返します。あなたもそれに噛ませてはいけません。 –