繁体   English   中英

Python parallel.future在完成之前停止

[英]Python concurrent.future stops before finished

我有一个简单的并发脚本设置,如下所示:

import concurrent.futures
import json
import requests
import datetime
import sys

from datetime import datetime
from time import sleep

executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)

poll_worker = None
request_headers = {"Content-Type": "application/json"}

def addBulkListings(bulk_listings):
    print("Adding listings")
    future = executor.submit(runBulkListings, bulk_listings)
    future.add_done_callback(addPollBulkID)

# Future callback
def addPollBulkID(future):
    if not future.exception():
        poll_id = future.result().json()['results']
        print("Polling id: %s" % poll_id)
        new_future = executor.submit(pollBulkListing, poll_id)
        new_future.add_done_callback(callProcessMatches)
        print(new_future.result())
    else:
        print("Error getting Poll ID")
        print(future.exception())

# Future callback
def callProcessMatches(future):
    print("callProcessMatches")
    if not future.exception():
        print("Processing matches")
        result = future.result()
        new_future = executor.submit(processMatches, result.json())
        new_future.add_done_callback(finishBulkListing)
    else:
        print("Error polling")
        print(future.exception())

# Future callback
def finishBulkListing(future):
    if not future.exception():
        print(future.result())
    else:
        print("Error processing matches")
        print(future.exception())

# Executor called
def processMatches(response):
    results = []

    for product in response['results']:
        processResults(product, results)

    return results

# Executor called
def pollBulkListing(poll_id):
    start = datetime.now()
    overtime = False

    while not overtime:
        response = requests.get(MAIN_URL + poll_id,
            headers = request_headers)
        if response.status_code == requests.codes.ok:
            return response
        sleep(5)
        overtime = (datetime.now() - start).seconds >= (1 * 60)

    raise requests.exceptions.Timeout

# Executor called
def runBulkListings(bulk_listings):
    response = requests.post(MAIN_URL, 
        data=json.dumps(bulk_listings),
        headers = request_headers)
    response.raise_for_status()
    return response

“ addBulkListing”由另一个脚本调用,然后该脚本开始与执行程序一起工作。 当我只调用一次addBulkListing时,我就已经完成了这项工作,但是如果我两次调用,都会失败。 “ addPollBulkID”方法中会出问题。 那里的打印语句将无例外地执行,但是程序仅退出。 无论是否有异常,“ callProcessMatches”中的任何内容均不会被调用。 就像我说的,当一切都很好时,我只调用addBulkListings。

猜猜:我一直在鬼混一段时间,但不确定。 在示例中,我看到人们使用:

with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:

但这创建了我不想要的上下文。 刚开始时,我并没有将所有参数都添加到“ addBulkListings”函数中,因此需要在不重新创建执行程序的情况下将其添加到其中。 也许我误会了一些东西。

谢谢你的帮助!

啊哈! 因此,如果有人需要,我将回答我自己的问题。 原来我能够通过切换到以下方式来修复它:

executor = concurrent.futures.ProcessPoolExecutor(max_workers=5)

而不是ThreadPoolExecutor。 我在想我创建的线程有一些内存重叠。 这个StackOverflow答案指出正确的方向(看第二个答案)对我有很大帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM