0

関数の実行時間を制限する必要があるため、Josh Leeの回答に従いました

try:
    with time_limit(10):
        long_function_call()
except TimeoutException, msg:
    print "Timed out!"

ここで、 long_function_call() は、ページとやり取りしていくつかの操作を行う Selenium Webdriver 関数です。

def long_function_call(self, userName, password):
    driver = self.initDriver()
    try: 
         driver.get("https://yyyy.com")
         time.sleep(2)
         if not self.isHttps(driver.current_url):
              isHttps = False             
         driver.find_element_by_id("i015516").clear()
         time.sleep(5)
         if 'https://yyy.com' not in driver.current_url:
             self.raiseFailedToLogin('yyy')                    
    except Exception as e:
        self.raiseException('yyy',e)
    finally:
        driver.close()
        driver.quit()
    return 'yyyy' 

ほとんどの場合、関数の実行時間がシグナル タイムアウトを超えるとシグナルが送信され、メソッドが停止しますが、場合によってはメソッドがタイムアウトを超えて停止しませんでした。Selenium がハングしているようです (firefox は開いていて、何もしていません)。

これらのケースでデバッガーを一時停止しようとしましたが、一時停止してもハングする場所が表示されませんでした。このメソッドでデバッグ一時停止よりもセレンFirefoxを閉じると:

_read_status [httplib.py:366]   
begin [httplib.py:407]  
getresponse [httplib.py:1030]   
do_open [urllib2.py:1180]   
http_open [urllib2.py:1207]
def _read_status(self):
    # Initialize with Simple-Response defaults
    line = self.fp.readline()
    if self.debuglevel > 0:  ################Hang here

場合によっては、セレンのシグナルアラームが機能しなかった理由は何ですか? (私は彼らが割り込みをキャッチするとは思わない)。

4

1 に答える 1

0

これはあなたが直面している非常に興味深い問題です。を使用する際に直面する可能性のある問題のいくつかを示す例を作成しましたwith time_limit。以下のコードを実行すると、1 秒後に aTimeoutExceptionが発生し、Python が終了し、実行中のスレッドと xterm がすべて終了するはずです。1 秒後に が発生TimeoutExceptionし、「Timed out!」が表示されます。端末に表示されますが、スレッドと xterm の両方が実行を継続します。これはおそらく、セレンで直面しているタイプのシナリオです。セレンがどのように実装されているかはわかりませんが、例にある xterm と同様の方法で firefox プロセスを生成する必要があります。

シンプルなアプローチ

import time, os, sys, subprocess, threading

def worker():
    for i in range(30):
        print i
        time.sleep(0.1)

try:
    with time_limit(1):
        threading.Thread(target=worker).start()
        subprocess.check_output('/usr/bin/xterm')
except TimeoutException, msg:
    print "Timed out!"

この問題の潜在的な解決策は、次のコードです。この場合、xterm を強制終了するこの python プログラムのすべての子プロセスを強制終了し、それから自分自身を強制終了します。もちろん、これは強制的な終了方法ですが、すべてがタイムアウトで終了することを保証します。

皆殺しにする

subprocess.call('pkill -P %s' % os.getpid(), shell=True)
subprocess.call('kill -9 %s' % os.getpid(), shell=True)

別のアプローチの下のコメントを考慮に入れると、メインスレッドでの操作が指定されたタイムアウトを超えた場合に kill 操作を実行する別のスレッドを持つことになります。これは、サンプル呼び出しを使用したそのアプローチの実装です。

タイムアウトを監視して強制終了するスレッド

import time, os
from subprocess import check_output, call
from threading import Thread
from contextlib import contextmanager

def wait_thread(active, duration):
    start = time.time()
    while active[0] and time.time() - start < duration:
        time.sleep(0.1)
    if active[0]:
        call('pkill -P %s' % os.getpid(), shell=True)
        call('kill -9 %s' % os.getpid(), shell=True)

@contextmanager
def wait(duration):
    active = [True]
    Thread(target=wait_thread, args=(active, duration)).start()
    yield
    active[0] = False

with wait(1):
    time.sleep(0.5)
    print 'finished safely before timeout'
with wait(1):
    call('/usr/bin/xterm')
于 2012-11-13T17:04:49.457 に答える