Python中的线程池

https://www.cnblogs.com/zhang293/p/7954353.html

from concurrent.futures import ThreadPoolExecutor

import time

def sayhello(a):
    print("hello: "+a)
    time.sleep(2)

def main():
    seed=["a","b","c"]
    start1=time.time()
    for each in seed:
        sayhello(each)
    end1=time.time()
    print("time1: "+str(end1-start1))
    start2=time.time()
    with ThreadPoolExecutor(3) as executor:
        for each in seed:
            executor.submit(sayhello,each)

    end2=time.time()
    print("time2: "+str(end2-start2))
    start3=time.time()
    with ThreadPoolExecutor(3) as executor:
        executor.map(sayhello,seed)
    end3=time.time()
    print("time3: "+str(end3-start3))

if __name__=="__main__":
    main()

运行结果:

hello: a
hello: b
hello: c
time1: 6.000343322753906
hello: a
hello: b
hello: c
time2: 2.0031144618988037
hello: a
hello: b
hello: c
time3: 2.0031144618988037

注意到一点:
concurrent.futures.ThreadPoolExecutor,在提交任务的时候,有两种方式,一种是submit()函数,另一种是map()函数,两者的主要区别在于:

  • map可以保证输出的顺序, submit输出的顺序是乱的
  • 如果你要提交的任务的函数是一样的,就可以简化成map。但是假如提交的任务函数是不一样的,或者执行的过程之可能出现异常(使用map执行过程中发现问题会直接抛出错误)就要用到submit()
  • submit和map的参数是不同的,submit每次都需要提交一个目标函数和对应的参数,map只需要提交一次目标函数,目标函数的参数放在一个迭代器(列表,字典)里就可以。
### Python线程池的任务执行顺序 在Python中,`concurrent.futures.ThreadPoolExecutor` 是用于实现线程池的标准库模块之一。尽管线程池的主要目的是并行化任务以提高性能,但在某些情况下可能需要保证任务的执行顺序。 #### 使用 `map()` 方法保持任务提交和完成的顺序 当使用 `ThreadPoolExecutor.map()` 提交一组函数调用时,返回的结果会按照任务被提交的顺序排列,而不管实际的执行时间长短。这意味着即使某个任务较慢,其结果仍然会在对应的位置上等待其他任务完成后才返回[^1]。 ```python from concurrent.futures import ThreadPoolExecutor, as_completed def task(n): import time time.sleep(0.5 / n) return f"Task {n} completed" with ThreadPoolExecutor(max_workers=3) as executor: results = list(executor.map(task, range(1, 4))) print(results) ``` 上述代码展示了如何利用 `executor.map()` 来确保输出列表中的元素严格遵循输入迭代器的顺序[^2]。 #### 利用 `as_completed()` 和手动排序来控制顺序 如果希望更灵活地处理已完成的任务但又想最终得到有序的结果,则可以先收集所有未来对象 (futures),待它们全部完成后按原始索引重新整理数据: ```python import concurrent.futures tasks = [] results_ordered = [] def compute(x): from random import randint delay = randint(1,3) print(f'Starting Task-{x}, sleeping for {delay}s') import time;time.sleep(delay) return x*x with concurrent.futures.ThreadPoolExecutor() as exe: futures_to_idx = { exe.submit(compute,i):i for i in range(5)} for future in concurrent.futures.as_completed(futures_to_idx): idx = futures_to_idx[future] try: result = future.result() results_ordered.append((idx,result)) except Exception as exc: print('%r generated an exception: %s' % (idx,exc)) sorted_results = [res for _, res in sorted(results_ordered)] print(sorted_results) ``` 这里通过记录每个 Future 对象关联的任务编号,在最后一步依据这些编号对结果进行了升序排列[^3]。 #### 总结 虽然多线程本质上支持异步操作,但是借助于合适的工具和技术——比如 `map()` 或者结合 `submit()` 配合自定义逻辑——我们可以有效地维持特定条件下所需的序列关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值