1

私はPythonを初めて使用し、2つのタスクを同時に実行しようとしています。これらのタスクはWebサーバー上のページをフェッチするだけであり、一方が他方の前に終了する可能性があります。すべてのリクエストが処理されたときにのみ結果を表示したい。Linuxシェルでは簡単ですが、Pythonではどこにも行きません。私が読んだすべてのハウツーは、私のような初心者には黒魔術のように見えます。以下のbashスクリプトの単純さに比べて、それらはすべて私には複雑に見えます。

Pythonでエミュレートしたいbashスクリプトは次のとおりです。

# First request (in background). Result stored in file /tmp/p1
wget -q -O /tmp/p1 "http://ursule/test/test.php?p=1&w=5" &
PID_1=$!

# Second request. Result stored in file /tmp/p2
wget -q -O /tmp/p2 "http://ursule/test/test.php?p=2&w=2"
PID_2=$!

# Wait for the two processes to terminate before displaying the result
wait $PID_1 && wait $PID_2 && cat /tmp/p1 /tmp/p2

test.phpスクリプトは単純です。

<?php
printf('Process %s (sleep %s) started at %s ', $_GET['p'], $_GET['w'], date("H:i:s"));
sleep($_GET['w']);
printf('finished at %s', date("H:i:s"));
?>

bashスクリプトは次を返します。

$ ./multiThread.sh
Process 1 (sleep 5) started at 15:12:59 finished at 15:12:04
Process 2 (sleep 2) started at 15:12:59 finished at 15:12:01

私がこれまでPython3で試したこと:

#!/usr/bin/python3.2

import urllib.request, threading

def wget (address):
    url = urllib.request.urlopen(address)
    mybytes = url.read()
    mystr = mybytes.decode("latin_1")
    print(mystr)
    url.close()

thread1 = threading.Thread(None, wget, None, ("http://ursule/test/test.php?p=1&w=5",))
thread2 = threading.Thread(None, wget, None, ("http://ursule/test/test.php?p=1&w=2",))

thread1.run()
thread2.run()

これは、次のように期待どおりに機能しません。

$ ./c.py 
Process 1 (sleep 5) started at 15:12:58 finished at 15:13:03
Process 1 (sleep 2) started at 15:13:03 finished at 15:13:05
4

2 に答える 2

1

スレッドを使用する代わりに、独立した各タスクとしてマルチプロセッシングモジュールを使用すると便利です。GIL(http://wiki.python.org/moin/GlobalInterpreterLock)の詳細をお読みください。

于 2013-01-01T08:16:23.800 に答える
0

あなたのアドバイスに従って、マルチスレッドとマルチプロセッシングに関するドキュメントページに飛び込み、いくつかのベンチマークを行った後、マルチプロセッシングがその仕事に適しているという結論に達しました. スレッド/プロセスの数が増えると、スケールアップが大幅に向上します。私が直面したもう 1 つの問題は、これらすべてのプロセスの結果を保存する方法でした。Queue.Queue を使用するとうまくいきました。これが私が思いついた解決策です:

このスニペットは、Anwser を返す前に 1 秒間一時停止するテスト リグに同時 http 要求を送信します (上記の php スクリプトを参照)。

import urllib.request

# function wget arg(queue, adresse)
def wget (resultQueue, address):
    url = urllib.request.urlopen(address)
    mybytes = url.read()
    url.close()
    resultQueue.put(mybytes.decode("latin_1"))

numberOfProcesses = 20

from multiprocessing import Process, Queue

# initialisation
proc = []
results = []
resultQueue = Queue()

# creation of the processes and their result queue
for i in range(numberOfProcesses):
    # The url just passes the process number (p) to the my testing web-server
    proc.append(Process(target=wget, args=(resultQueue, "http://ursule/test/test.php?p="+str(i)+"&w=1",)))
    proc[i].start()

# Wait for a process to terminate and get its result from the queue
for i in range(numberOfProcesses):
    proc[i].join()
    results.append(resultQueue.get())

# display results
for result in results:
    print(result)
于 2013-01-01T20:21:30.487 に答える