Python 为什么ThreadPool没有';I don’过了一段时间后,我不会再下一步行动了

Python 为什么ThreadPool没有';I don’过了一段时间后,我不会再下一步行动了,python,multithreading,timeout,threadpool,Python,Multithreading,Timeout,Threadpool,我的目标是: 浏览网站列表,使用请求检查它们。这是在apply\u job中完成的 我的问题是: 调用job\u pool.next时,一些网站出现错误,它们没有给出错误,而是站在那里,甚至没有给出TimeoutError。这就是为什么我在next函数中使用10秒超时的原因。此超时工作正常,但当出现TimeoutError异常时,next功能在以下时间持续引发异常,即使下一个网站正常。在我看来,它似乎没有移动到下一个项目,只是在同一个项目上循环 我试过使用imap和imap\u unord

我的目标是:

  • 浏览网站列表,使用请求检查它们。这是在
    apply\u job
    中完成的
我的问题是:

  • 调用
    job\u pool.next
    时,一些网站出现错误,它们没有给出错误,而是站在那里,甚至没有给出
    TimeoutError
    。这就是为什么我在
    next
    函数中使用10秒超时的原因。此超时工作正常,但当出现
    TimeoutError
    异常时,
    next
    功能在以下时间持续引发异常,即使下一个网站正常。在我看来,它似乎没有移动到下一个项目,只是在同一个项目上循环
  • 我试过使用
    imap
    imap\u unordered
    ,两者没有区别
我的代码在这里:

   def run_check(websites):
        """ Run check on the given websites """
        import multiprocessing
        from multiprocessing.pool import ThreadPool

        pool = ThreadPool(processes=JOB_POOL_SIZE)

        try:
            job_pool = pool.imap_unordered(apply_job, websites)

            try:
                while True:
                    try:
                        res = job_pool.next(10)
                    except multiprocessing.TimeoutError:
                        logging.error("Timeout Error")
                        res = 'No Res'

                    csv_callback(res)

            except StopIteration:
                pass

            pool.terminate()
        except Exception, e:
            logging.error("Run_check Error: %s"%e)
            raise
我使用
res=requests.get(url,timeout=10)
检查网站。此超时不适用于此问题

为了测试,这里有一些产生问题的网站(不是每次都有,但经常有):

我不知道这些网站有什么不同,但我猜它们每隔一段时间就会发送一个字节,所以即使它们无法使用,也不会被认为是真正的超时

如果有人有什么想法,我将不胜感激,我已经坚持了好几天了。我甚至尝试了
future
async
,但它们没有引发我需要的异常


谢谢大家

您认为将超时传递到下一个
会中止作业的直觉是错误的。它只是中止等待,但特定作业仍在运行。下次你等待的时候,你确实在等待同样的工作。要在实际作业上实现超时,您应该查看。请注意,没有可靠的方法终止另一个线程。因此,如果您绝对无法使作业在合理的时间范围内终止,您可以切换到基于进程的池并强制终止进程(例如,使用
signal.alarm
)。

我找到了解决问题的方法,我使用了
eventlet
及其
Timeout
函数。

此解决方案运行良好,因为它会在函数
网站的整个执行过程中超时。请在命令
url,result=tpool.execute(website.try\u url,account\u website)
中尝试url

def apply_job(account_info):
    """ Job for the Thread """
    try:
        account_id = account_info['id']
        account_website = account_info['website']
        url = account_website
        result = "ERROR: GreenPool Timeout"
        with Timeout(TIMEOUT*2, False):
            url, result = tpool.execute(website.try_url, account_website)

        return (account_id, account_website, url, result)

    except Exception, e:
        logging.error("Apply_job Error: %s"%e)

def start_db(res):
    update_db(res)
    csv_file.csv_callback(res)

def spawn_callback(result):
    res = result.wait()
    tpool.execute(start_db, res)

def run_check(websites):
    """ Run check on the given websites """
    print str(len(websites)) + " items found\n"

    pool = eventlet.GreenPool(100)
    for i, account_website in enumerate(websites):
        res = pool.spawn(apply_job, account_website)
        res.link(spawn_callback)

    pool.waitall()