如何确保 while 在各个方面都停止
How to make sure that while will stop in every respect
我正在为 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
更新
我不确定 while
是否只会受到 while
中编写的代码的影响,或者是否有其他方面可能会影响 while
过程。
更新 2
一项检查是否 get()
returns 错误的测试。使用 Python 3.x 而不是 Python 2.x 进行测试,这是 KODI 使用的。
更新 3
查看是否 get()
returns 引发错误的测试。使用 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
错误不是发生在 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()
都可以用来检查结果是否有错误。
我正在为 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
更新
我不确定 while
是否只会受到 while
中编写的代码的影响,或者是否有其他方面可能会影响 while
过程。
更新 2
一项检查是否 get()
returns 错误的测试。使用 Python 3.x 而不是 Python 2.x 进行测试,这是 KODI 使用的。
更新 3
查看是否 get()
returns 引发错误的测试。使用 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
错误不是发生在 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()
都可以用来检查结果是否有错误。