루프의 일부가 하위 프로세스 인 지정된 시간 후에 완료되지 않은 경우 루프를 다시 시작하는 방법이 있습니까?지정된 시간 후 루프 위치 다시 시도
subprocess.Popen()
을 사용하여 다른 작업자 스크립트의 X 인스턴스를 생성하는 main.py
스크립트가 있습니다. 각 "작업자"는 본질적으로 작업 (각기 다른 기능과 작업을 제공하는 작업자와 대기열)에 대해 Azure에서 호스팅되는 각각의 대기열을 확인합니다.
문제는 andy
작업자 (andy.py
)가 가끔 함수를 호출하는 while
루프의 특정 부분에서 멈추는 경향이 있다는 것입니다. 나는 SIGALRM을 사용하여 어떤 일을 저지하려고 시도했는데, 이는 단순히 pass
을 호출하는 예외를 발생시킨다. signal.alarm()
은 시도를 중단하고 while
루프에 있기 때문에 다시 검색을 시도합니다.
알람은 알람이 시작될 때와 마찬가지로 실행중인 완전히 다른 하위 프로세스에도 영향을 미치며 때로는 실행중인 작업을 방해합니다. 내가 원하는 것은 함수가 완료하는 데 X 초 이상 걸리는 경우 함수를 다시 실행하려고하는 것입니다. 여기
코드가 어떻게 생겼는지의 예입니다 (사람을위한 runable이다 부여 기능은 코드로 대체되었고, 나는andy
이외의 근로자 실행하는 모든 기능을 제거했습니다) :
을 의 main.py
import subprocess as sp
import sys
import time
import datetime
import thread
max_workers = {'andy': 10}
def check():
workers = {'andy': {}}
while True:
for worker, instances in workers.items():
while len(instances) < max_workers[worker]:
process = sp.Popen(['python', 'workers/%s.py' % worker], shell=False)
workers[worker][process] = process.pid
for worker, instances in workers.items():
for process, pid in instances.items():
if process.poll() is not None:
del workers[worker][process]
def time_check():
global max_workers
start = datetime.time(hour=07, minute=05)
end = datetime.time(hour=23, minute=00)
while 1:
now = datetime.datetime.now().time().replace(second=0, microsecond=0)
if now == start:
time.sleep(60)
max_workers['andy'] = 7
elif now == end:
time.sleep(60)
max_workers['andy'] = 0
else:
time.sleep(1)
if __name__ == "__main__":
while 1:
try:
thread.start_new_thread(check,())
thread.start_new_thread(time_check,())
except KeyboardInterrupt:
sys.exit(0)
andy.py
import datetime
import otas
import json
import time
import signal
def alarm_handler():
pass
def start():
resort_ids = 'Los Angeles', 'New York', 'Chicago', 'Miami'
start_date = datetime.datetime.now()
end_date = start_date + datetime.timedelta(days=10)
ota = otas.Expedia(headless=False)
signal.signal(signal.SIGALRM, alarm_handler)
for resort_id in resort_ids:
search_date = start_date
while search_date < end_date:
signal.alarm(15)
try:
data = ota.search_by_date(resort=resort_id, checkin=search_date)
except:
pass
else:
try:
print data
except TypeError:
pass
search_date += datetime.timedelta(days=1)
if __name__ == '__main__':
start()
otas.py
from selenium import webdriver
import datetime
class Expedia:
def __init__(self, headless=True):
if headless is True:
self.driver = webdriver.PhantomJS()
else:
self.driver = webdriver.Firefox()
def search_by_date(self, resort, checkin, flexibility=4, nights=3):
driver = self.driver
try:
driver.get(
'http://www.expedia.com/Hotel-Search?#&destination={0}&startDate={1}&endDate={2}'.format(
resort, checkin.strftime("%m/%d/%Y"), (checkin + datetime.timedelta(days=1)).strftime("%m/%d/%Y")
)
)
return driver.page_source
except Exception, e:
return e
EDIT4 : 재 작성 질문 코드는 사용자를 재현 할 수 있으며, 더 명확합니다.
프로세스 생성 스크립트에서 'sigalrm'을 보내면 여전히 문제가 발생합니까 (예 : 아래 예). – user3467349
질문에 [XY 문제] (http://meta.stackexchange.com/a/66378/137096)와 같은 여러 문제가 있습니다. 서브 프로세스를 죽이기 위해서 무엇을하려고하는지 설명하고,'SIGALRM'을 쓰지 않아도된다. * 부모의 데드 라인 뒤에'process.kill()'을 호출하면된다. [당신의 문제를 보여주는 최소한의 예제를 만드십시오.] (http://stackoverflow.com/help/mcve) -이 호출없이 문제가 사라지지 않으면'strftime()','log.error()'를 포함하지 마십시오. – jfs
@ J.F.Sebastian 위의 코드를 수정하여'log.error()'또는'strftime()'을 포함하지 않고, 내가하고있는 일을 명확히하려고 노력했다. 나는 그 과정을 죽이려고하지 않고있다. 'ota.search_by_date()'는'andy.py '에서'import ota'로 가져 오는 함수입니다. 그것은'end_date'에 도달 할 때까지 날짜들을 반복하기로되어 있습니다. 각 날짜는 가져온 함수를 실행하여 제공된 '검색 날짜'에 호텔의 가용성을 반환합니다. – crookedleaf