【发布时间】:2017-07-02 03:42:43
【问题描述】:
我已经阅读了很多关于 SO 和其他地方关于这个主题的问题,但无法让它发挥作用。可能是因为我用的是Windows,我不知道。
我要做的是并行下载一堆文件(其 URL 是从 CSV 文件中读取的)。我已经尝试过使用multiprocessing 和concurrent.futures,但没有成功。
主要问题是我无法在 Ctrl-C 上停止程序 - 它只是继续运行。这在进程而不是线程的情况下尤其糟糕(我为此使用了multiprocessing),因为我每次都必须手动终止每个进程。
这是我当前的代码:
import concurrent.futures
import signal
import sys
import urllib.request
class Download(object):
def __init__(self, url, filename):
self.url = url
self.filename = filename
def perform_download(download):
print('Downloading {} to {}'.format(download.url, download.filename))
return urllib.request.urlretrieve(download.url, filename=download.filename)
def main(argv):
args = parse_args(argv)
queue = []
with open(args.results_file, 'r', encoding='utf8') as results_file:
# Irrelevant CSV parsing...
queue.append(Download(url, filename))
def handle_interrupt():
print('CAUGHT SIGINT!!!!!!!!!!!!!!!!!!!11111111')
sys.exit(1)
signal.signal(signal.SIGINT, handle_interrupt)
with concurrent.futures.ThreadPoolExecutor(max_workers=args.num_jobs) as executor:
futures = {executor.submit(perform_download, d): d for d in queue}
try:
concurrent.futures.wait(futures)
except KeyboardInterrupt:
print('Interrupted')
sys.exit(1)
我在这里尝试以两种不同的方式捕捉 Ctrl-C,但它们都不起作用。后一个(except KeyboardInterrupt)实际上已运行,但调用sys.exit后进程不会退出。
在此之前,我像这样使用multiprocessing 模块:
try:
pool = multiprocessing.Pool(processes=args.num_jobs)
pool.map_async(perform_download, queue).get(1000000)
except Exception as e:
pool.close()
pool.terminate()
sys.exit(0)
那么,在终端中按下 Ctrl-C 后,添加终止所有工作线程或进程的能力的正确方法是什么?
系统信息:
- Python 版本:3.6.1 32 位
- 操作系统:Windows 10
【问题讨论】:
-
至少对于多处理模块,这是一个已知的错误:bugs.python.org/issue8296 另见stackoverflow.com/questions/1408356/…
-
这个对我有用。试试stackoverflow.com/a/31795242/4385319
标签: python multithreading multiprocessing threadpoolexecutor