Я пишу скрипт для KODI, и я обнаружил бесконечный цикл, когда есть ошибка кода. Этот цикл означает, что мне нужно войти в другой аккаунт или перезагрузить компьютер, чтобы остановить KODI.Как убедиться, что во время остановки во всех отношениях
Мой вопрос, поэтому, как я могу убедиться, что while
остановится во всех отношениях?
Это лишь часть сценария, и что коды заворачивают в try
. Вам также необходимо знать, что try
всегда работает, если я вызываю ошибку.
Проблема в коде while
часть, например. на p.get()
. Это приводит к ошибке, потому что я не проверял, завершилась ли работа до того, как я позвоню get()
(я не исправил эту ошибку для вас).
Проблема в том, что, хотя я использую try
, непредвиденная ошибка приведет к тому, что while
не остановится!
def browse(separate, page):
[...]
# Getting meta data and subtitles
pools = {'metadata': [], 'subtitles': []}
with closing(multiprocessing.Pool(processes=2)) as pool:
provider_meta = call_provider(PROVIDERS['meta_tmdb'])
provider_subtitle = call_provider(PROVIDERS['subtitle_subscene'])
for item in items:
pools['metadata'].append(pool.apply_async(provider_meta.get, args=(item["info"]["code"], item["label"], item["info"]["year"]), callback=pool_stats))
pools['subtitles'].append(pool.apply_async(provider_subtitle.get, args=(item["info"]["code"], item["label"], item["info"]["year"]), callback=pool_stats))
pool_checklist = _create_checklist(pools)
while not xbmc.abortRequested and not dialog.iscanceled():
xbmc.sleep(100)
# Check if are raise a error
for p in pool_checklist:
p.get()
# Break when all requests are done
if all(p.ready() for p in pool_checklist):
break
else:
return
[...]
def _create_checklist(pools):
plist = []
for c in pools.values():
for p in c:
plist.append(p)
return plist
UPDATE
Я не уверен, является ли while
будет зависеть только от кодов, записанных в while
или есть и другие аспекты, которые могут повлиять на процесс while
ли.
UPDATE 2
тест, чтобы увидеть, если get()
возвращает ошибку. Протестировано с Python 3.x, а не с Python 2.x, что и использует KODI.
UPDATE 3
тест, чтобы увидеть, если get()
возвращает ошибку рейза. Протестировано с помощью Python 3.4.2 и Python 2.7.10.
from multiprocessing import Pool
from contextlib import closing
import time
def func(x, i):
if i == 10:
raise Exception('ttt')
return {'x':i}
def go():
try:
def callback(x):
print('done: '+str(x['x']))
pools = []
with closing(Pool(processes=2)) as pool:
for i in range(20):
pools.append(pool.apply_async(func, args=(i,i), callback=callback))
while not all(p.ready() for p in pools):
time.sleep(1)
list = map(lambda p: p.get(), pools)
for l in list:
print(l)
print('Finished with the script')
except:
print('ERROR')
if __name__ == '__main__':
go()
UPDATE 4
вопросы еще:
- Являются
while
влияет только кодов, написанных в вwhile
процессеwhile
или могут другие аспекты влияют ? - Как я могу убедиться, что
while
остановится во всех отношениях?
UPDATE 5
Это не кажется, что есть решение, где while
остановится во всех отношениях. Поэтому я считаю, что простым решением было бы проверить пулы после while
.
def browse(separate, page):
[...]
# Getting meta data and subtitles
pools = {'metadata': [], 'subtitles': []}
with closing(multiprocessing.Pool(processes=2)) as pool:
provider_meta = call_provider(PROVIDERS['meta_tmdb'])
provider_subtitle = call_provider(PROVIDERS['subtitle_subscene'])
for item in items:
pools['metadata'].append(pool.apply_async(provider_meta.get, args=(item["info"]["code"], item["label"], item["info"]["year"]), callback=pool_stats))
pools['subtitles'].append(pool.apply_async(provider_subtitle.get, args=(item["info"]["code"], item["label"], item["info"]["year"]), callback=pool_stats))
pool_checklist = _create_checklist(pools)
while not all(p.ready() for p in pool_checklist):
if xbmc.abortRequested or dialog.iscanceled()
return
xbmc.sleep(100)
# Check the pools for errors
for p in pool_checklist:
p.get()
[...]
def _create_checklist(pools):
plist = []
for c in pools.values():
for p in c:
plist.append(p)
return plist
Из вашего использования «Пул» Я предполагаю, что вы используете многопроцессорность. Если дочерний процесс вызывает исключение, я не думаю, что это приведет к тому, что основной процесс перестанет выполняться, поэтому цикл while продолжится. – Kevin
@Kevin Да, я использую многопроцессорность :) Но да, пул будет продолжаться до тех пор, пока он не закончится, однако 'get()' вернет ошибку, если бы был рейз один. –
Вы уверены, что 'get' поднимет ошибку? Каков тип 'p'? – Kevin