当前位置: 首页 > 面试题库 >

如何使用并发超时功能?

殷宾白
2023-03-14
问题内容

我正在尝试使用current.futures模块使超时在python3.2中工作。但是,当它超时时,并不会真正停止执行。我尝试了使用线程和进程池执行器,但它们都没有停止任务,只有直到完成后,超时才会增加。那么,有谁知道是否有可能使它起作用?

import concurrent.futures
import time
import datetime

max_numbers = [10000000, 10000000, 10000000, 10000000, 10000000]

def run_loop(max_number):
    print("Started:", datetime.datetime.now(), max_number)
    last_number = 0;
    for i in range(1, max_number + 1):
        last_number = i * i
    return last_number

def main():
    with concurrent.futures.ProcessPoolExecutor(max_workers=len(max_numbers)) as executor:
        try:
            for future in concurrent.futures.as_completed(executor.map(run_loop, max_numbers, timeout=1), timeout=1):
                print(future.result(timeout=1))
        except concurrent.futures._base.TimeoutError:
            print("This took to long...")

if __name__ == '__main__':
    main()

问题答案:

据我所知,TimeoutError实际上是在您期望的时间引发的,而不是在任务完成之后引发的。

但是,您的程序本身将继续运行,直到完成所有正在运行的任务。这是因为当前正在执行的任务(在您的情况下,可能是所有已提交的任务,因为您的池大小等于任务数)实际上并未被“杀死”。

引发TimeoutError,以便您可以选择不等到任务完成(而是执行其他操作),但是任务将继续运行直到完成。只要执行器的线程/子进程中有未完成的任务,python就不会退出。

据我所知,不可能仅“停止”当前正在执行的期货,而只能“取消”尚未开始的计划任务。在您的情况下,将没有任何东西,但是假设您有5个线程/进程的池,并且您想处理100个项目。在某个时候,可能有20个完成的任务,5个正在运行的任务和75个计划的任务。在这种情况下,您可以取消这76个计划的任务,但是无论您是否等待结果,正在运行的4个任务将一直持续到完成。

即使无法做到这一点,我想也应该有一些方法来达到您期望的最终结果。也许此版本可以在途中为您提供帮助(不确定其功能是否完全符合您的要求,但可能有一定用处):

import concurrent.futures
import time
import datetime

max_numbers = [10000000, 10000000, 10000000, 10000000, 10000000]

class Task:
    def __init__(self, max_number):
        self.max_number = max_number
        self.interrupt_requested = False

    def __call__(self):
        print("Started:", datetime.datetime.now(), self.max_number)
        last_number = 0;
        for i in xrange(1, self.max_number + 1):
            if self.interrupt_requested:
                print("Interrupted at", i)
                break
            last_number = i * i
        print("Reached the end")
        return last_number

    def interrupt(self):
        self.interrupt_requested = True

def main():
    with concurrent.futures.ThreadPoolExecutor(max_workers=len(max_numbers)) as executor:
        tasks = [Task(num) for num in max_numbers]
        for task, future in [(i, executor.submit(i)) for i in tasks]:
            try:
                print(future.result(timeout=1))
            except concurrent.futures.TimeoutError:
                print("this took too long...")
                task.interrupt()


if __name__ == '__main__':
    main()

通过为每个“任务”创建一个可调用对象,并将其提供给执行器,而不仅仅是简单的函数,您可以提供一种“中断”任务的方法。提示:删除task.interrupt()一行,看看会发生什么,这可能会使您更容易理解我在上面的详细解释;-)



 类似资料:
  • 问题内容: 我想编写一个代码,要求输入用户名,但时间限制为15秒。如果用户超过限制并且未能输入名称(或任何字符串),则代码将终止,并且将显示“超时”消息,否则应保存名称并显示“谢谢”消息。我曾经尝试过这种方法,但是这是错误的&无法正常工作。请给我一个解决方案。。谢谢。 问题答案: 该虚拟程序可能会帮助您: 更新: 这是经过测试的代码。 另外,我从man那里得到了一些提示。本手册已包含一个代码段,该

  • 本文向大家介绍Go语言如何并发超时处理详解,包括了Go语言如何并发超时处理详解的使用技巧和注意事项,需要的朋友参考一下 实现原理: 并发一个函数,等待1s后向timeout写入数据,在select中如果1s之内有数据向其他channel写入则会顺利执行,如果没有,这是timeout写入了数据,则我们知道超时了。 实现代码: 总结 以上就是这篇文章的全部内容,希望对大家的学习或者工作带来一定的帮助,

  • 问题内容: 我有一个小的jquery片段,该页面在屏幕顶部显示通知消息,以响应页面上的用户操作。该通知通常在Ajax操作之后显示,其中包含动态内容。 例如: 该通知运行良好,除非用户连续快速执行两个或多个操作,否则超时功能将使自己感到困惑,并且第二条消息似乎在之前的3000毫秒之内。 如果执行新操作,是否有办法“杀死”先前的通知。我对动作/选择器没有问题,只是TimeOut函数....要么停止它,

  • 问题内容: 我正在尝试为特定功能实现超时。我检查了SE中的许多问题,找不到适合我问题的解决方案,因为: 我在Windows中运行python 超时是在我无法控制的python函数上应用的,即它是在已经设计好的模块中定义的。 python函数不是子进程 我已经为特定任务开发了一个已经设计好的定制模块(例如),并且其中定义了功能。其中一个功能(例如)由于外部因素而倾向于永久运行,而我只是不希望pyth

  • 问题内容: 在jersey 1中,我们在类中具有一个函数setConnectTimeout。 在球衣2中,缺少此功能的地方使用该类。 如何在jersey 2.x中设置连接超时并读取超时? 问题答案: 下面的代码在Jersey 2.3.1中对我有用(灵感在这里找到:https :

  • 我的程序应该使用多线程运行很长时间。我需要为线程设置超时的能力,一旦线程终止,我想重新启动它。这是我的代码: