2015-06-25 10 views
0

Я пишу скрипт для 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 
+0

Из вашего использования «Пул» Я предполагаю, что вы используете многопроцессорность. Если дочерний процесс вызывает исключение, я не думаю, что это приведет к тому, что основной процесс перестанет выполняться, поэтому цикл while продолжится. – Kevin

+0

@Kevin Да, я использую многопроцессорность :) Но да, пул будет продолжаться до тех пор, пока он не закончится, однако 'get()' вернет ошибку, если бы был рейз один. –

+0

Вы уверены, что 'get' поднимет ошибку? Каков тип 'p'? – Kevin

ответ

0

ошибка произошла не get(), но с мишенью в apply_async(). Поэтому это решение позволило остановить процесс снова.

Вывод: это. Цикл будет продолжаться, хотя есть ошибка с Pool, и поэтому вы всегда можете выйти из цикла.

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) 
     # Loop 
     while not all(p.ready() for p in pool_checklist): 
      if xbmc.abortRequested or dialog.iscanceled(): 
       return 
      xbmc.sleep(100) 
     # Check the results for errors 
     for p in pool_checklist: 
      p.get() 
    [...] 

Кроме того следует отметить для Python 3.4.2 и 2.7.10, что Pool поднимет только ошибку, когда он будет завершен, и любое дополнительным может get() использоваться для проверки результатов на наличии ошибок.