8

接続が中断された場合に備えて、Python アプリケーションの 1 つをもう少し堅牢にしようとしているときに、urllib2 によって作成された http ストリームの読み取り関数を呼び出すと、スクリプトが永久にブロックされる可能性があることがわかりました。

読み取り関数がタイムアウトし、最終的に例外が発生すると思いましたが、読み取り関数の呼び出し中に接続が中断された場合はそうではありません。

問題を引き起こすコードは次のとおりです。

import urllib2

while True:
    try:
        stream = urllib2.urlopen('http://www.google.de/images/nav_logo4.png')
        while stream.read(): pass
        print "Done"
    except:
        print "Error"

(スクリプトを試してみると、スクリプトが回復しない状態になる前に、おそらく数回接続を中断する必要があります)

Winpdb 経由でスクリプトを見て、スクリプトが回復しない状態のスクリーンショットを作成しました (ネットワークが再び使用可能になった場合でも)。

Winpdb http://img10.imageshack.us/img10/6716/urllib2.jpg

ネットワーク接続が中断された場合でも信頼できる動作を継続する Python スクリプトを作成する方法はありますか? (余分なスレッド内でこれを行うことは避けたいと思います。)

4

2 に答える 2

7

次のようなものを試してください:

import socket
socket.setdefaulttimeout(5.0)
   ...
try:
   ...
except socket.timeout:
   (it timed out, retry)
于 2009-05-01T14:57:26.103 に答える
2

良い質問です。答えを見つけることに本当に興味があります。私が考えることができる唯一の回避策は、 python docsで説明されているシグナルトリックを使用することです。あなたの場合は、次のようになります。

import signal
import urllib2

def read(url):
    stream = urllib2.urlopen(url)
    return stream.read()

def handler(signum, frame):
    raise IOError("The page is taking too long to read")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This read() may hang indefinitely
try:
    output = read('http://www.google.de/images/nav_logo4.png')
except IOError:
    # try to read again or print an error
    pass

signal.alarm(0)          # Disable the alarm
于 2009-05-01T14:32:14.243 に答える