2012-03-16 16 views
2
私は質問を熟読した

のタイムアウトを設定しますトマシュの編集中に最初のソリューションで実験されて(わかりやすくするためにここに再掲):は、ここに掲載mechanize.Browser

import signal, time 

def request(arg): 
    """Your http request""" 
    time.sleep(2) 
    return arg 

class Timeout(): 
    """Timeout class using ALARM signal""" 
    class Timeout(Exception): pass 

    def __init__(self, sec): 
    self.sec = sec 

    def __enter__(self): 
    signal.signal(signal.SIGALRM, self.raise_timeout) 
    signal.alarm(self.sec) 

    def __exit__(self, *args): 
    signal.alarm(0) # disable alarm 

    def raise_timeout(self, *args): 
    raise Timeout.Timeout() 

# Run block of code with timeouts 
try: 
    with Timeout(3): 
    print request("Request 1") 
    with Timeout(1): 
    print request("Request 2") 
except Timeout.Timeout: 
    print "Timeout" 

# Prints "Request 1" and "Timeout" 

私が使用して自分の端末からこれを実行するとpython timeout.py(バージョンはPython 2.7.2+であると私はUbuntuの11.10オンにしていますeiricオセロット)、代わりに、それは単に

を印刷し
Request 1 
Request 2 

thrown-も例外ではありません誰かがこの問題を解決する方法について説明していただけますか?それらのsignal.alarmsignal.signalコールで起こっていることの説明もすばらしいでしょう。

ありがとうございます!

EDIT:

実行strace -f python timeout.py利回り:あなたはここで何が起こるかを知りたい場合は

alarm(3)        = 0 
select(0, NULL, NULL, NULL, {2, 0})  = 0 (Timeout) 
fstat64(1, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb740c000 
alarm(0)        = 1 
rt_sigaction(SIGALRM, {0x812f450, [], 0}, {0x812f450, [], 0}, 8) = 0 
alarm(1)        = 0 
select(0, NULL, NULL, NULL, {2, 0})  = 0 (Timeout) 
alarm(0)        = 0 
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, {0x812f450, [], 0}, 8) = 0 
rt_sigaction(SIGALRM, {SIG_DFL, [], 0}, {0x812f450, [], 0}, 8) = 0 
write(1, "Request 1\nRequest 2\n", 20) = 20 
exit_group(0)       = ? 
+1

'sleep'は内部的に' SIGALRM'を使用しているかもしれませんが、それはもっともらしく、あなたのテストを台無しにするでしょう。スリープの代わりにI/Oをブロックする(単にstdinから読み込み、コンソールには何も入力しない)ようにしてください。 – Useless

+1

それは私のために、同じバージョンのUbuntuで動作します。あなたは '#!/ usr/bin/env python'や' chmod 777 'を忘れていませんでしたか? – John

+0

私の環境(cPython 2.6.5/ubuntu 9.04)でコードが正常に動作します –

答えて

1

は、試してみてください。私にとって

$ strace -f python timeout.py 

(のpython 2.6でのDebian 6を実行しています)これは機能します。重要な部分のstrace出力:

alarm(3)        = 0 
select(0, NULL, NULL, NULL, {2, 0})  = 0 (Timeout) 
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 15), ...}) = 0 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = x7f0fbbe06000 
write(1, "Request 1\n", 10Request 1)    = 10 
alarm(0)        = 1 
rt_sigaction(SIGALRM, {0x4d0a90, [], SA_RESTORER, 0x7f0fbb9deff0}, {0x4d0a90, [], SA_RESTORER, 0x7f0fbb9deff0}, 8) = 0 
alarm(1)        = 0 
select(0, NULL, NULL, NULL, {2, 0})  = ? ERESTARTNOHAND (To be restarted) 
--- SIGALRM (Alarm clock) @ 0 (0) --- 
rt_sigreturn(0xffffffff)    = -1 EINTR (Interrupted system call) 
alarm(0)        = 0 
write(1, "Timeout\n", 8Timeout 
)    = 8 

アラーム(3)が呼び出されます。リクエスト1が届きます。タイムアウトを与えるalarm(1)が呼び出されます。

+0

私は 'strace'の出力を編集に投稿しました。私は本当になぜこれが私のためにはうまくいかないのか混乱していますが、他の人のためには 'write'コマンドが一度呼び出されて例外がスローされることはありません。何か案は?ありがとう。 – ZenLikeThat

関連する問題