0

KODI 用のスクリプトを書いていますが、コード エラーがあると無限ループが発生することがわかりました。このループは、別のアカウントにログインするか、コンピューターを再起動して KODI を停止する必要があることを意味します。

whileしたがって、私の質問は、それがあらゆる点で確実に停止するようにするにはどうすればよいですか?


これはスクリプトの一部であり、コードはtry. tryまた、エラーが発生した場合でも常に機能することを知っておく必要があります。

コードの問題は、while例えば at の部分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

アップデート

whileのみが に記述されたコードの影響を受けるのか、プロセスwhileに影響を与える可能性のある他の側面があるのか​​ はわかりません。while


更新 2

get()エラーが返されるかどうかを確認するテスト。KODI が使用している Python 2.x ではなく、Python 3.x でテストされています。


更新 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()

更新 4

質問はまだあります:

  • whileに記述されたコードによってのみ影響を受けますか、それともwhile他の側面がwhileプロセスに影響を与える可能性がありますか?
  • whileあらゆる点で意志が停止することを確認するにはどうすればよいですか?

更新 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
4

1 に答える 1

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()でエラーの結果を確認するために使用できます。

于 2015-06-25T16:51:54.820 に答える