我因爲聽了這個問題張貼在這裏:設置超時mechanize.Browser
What should I do if socket.setdefaulttimeout() is not working?
,試圖拿出一個解決方案,殺死請求時,我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山貓),沒有例外thrown-相反,它只是簡單地打印
Request 1
Request 2
可能有人請解釋如何解決這一問題?對這些signal.alarm
和signal.signal
調用進行的解釋也很棒。
非常感謝您的寶貴時間!
編輯:
運行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) = ?
也許'sleep'使用'SIGALRM'內部,這是合理的,並會弄亂你的測試。嘗試做一個阻塞I/O操作而不是睡眠(從標準輸入讀取,不要在控制檯輸入任何東西)。 – Useless 2012-03-16 16:11:45
它適用於我,同一版本的Ubuntu。你沒有忘記'#!/ usr/bin/env python'或'chmod 777'是不是? –
John
2012-03-16 16:14:38
代碼工作在我的環境預期(CPython的2.6.5/Ubuntu的9.04) – 2012-03-16 16:16:33