python 线程池调用返回结果处理

python多线程调用,如果使用threading.Thread这个如果没有返回值完全没问题,但是有返回的时候就很有问题
下面是一个sample

import  threading,os,time,datetime
def fun1(num):
    print(f"线程名称:{threading.current_thread().getName()},线程ID:{threading.get_ident()},进程ID:{os.getpid()},开始时间:{datetime.datetime.now()}")
    time.sleep(1)
    print(f"执行第{num}次fun1函数")
    print(f"线程名称:{threading.current_thread().getName()},线程ID:{threading.get_ident()},进程ID:{os.getpid()},结束时间:{datetime.datetime.now()}")

if __name__=='__main__':
    tasks=[]
    for i in range(10):
        t=threading.Thread(target=fun1,args=(i,))
        tasks.append(t)
        t.start()
    for i in tasks:
        i.join()

运行结果:

import  threading,os,time,datetime
def fun1(num):
    print(f"线程名称:{threading.current_thread().getName()},线程ID:{threading.get_ident()},进程ID:{os.getpid()},开始时间:{datetime.datetime.now()}")
    time.sleep(1)
    print(f"执行第{num}次fun1函数")
    print(f"线程名称:{threading.current_thread().getName()},线程ID:{threading.get_ident()},进程ID:{os.getpid()},结束时间:{datetime.datetime.now()}")

if __name__=='__main__':
    tasks=[]
    for i in range(10):
        t=threading.Thread(target=fun1,args=(i,))
        tasks.append(t)
        t.start()
    for i in tasks:
        i.join()

为了获取线程池执行的返回结果我们采用map方法

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}".format(datetime.datetime.now()))
    time.sleep(1)
    return a+b

if __name__=='__main__':
    with ThreadPoolExecutor(5) as t:
        res=t.map(add,L1,L2)
    print(res,type(res),list(res))
    print("============程序结束=============={}".format(datetime.datetime.now()))

返回结果:

============程序开始时间==============2022-07-08 10:48:45.342660
============程序开始时间==============2022-07-08 10:48:45.342957
============程序开始时间==============2022-07-08 10:48:45.343087
============程序开始时间==============2022-07-08 10:48:45.343184
============程序开始时间==============2022-07-08 10:48:45.343466
============程序开始时间==============2022-07-08 10:48:46.344016
============程序开始时间==============2022-07-08 10:48:46.344077
============程序开始时间==============2022-07-08 10:48:46.344096
============程序开始时间==============2022-07-08 10:48:46.344114
============程序开始时间==============2022-07-08 10:48:46.344211
<generator object Executor.map.<locals>.result_iterator at 0x7f99ae76df90> <class 'generator'> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
============程序结束==============2022-07-08 10:48:47.345554

这个map返回的结果集是根据执行顺序来的,为社么这么说,我们改写代码:

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
# def fn(res):
#     print(res.result())
#     return res.result()

if __name__=='__main__':
    with ThreadPoolExecutor(5) as t:
        res=t.map(add,L1,L2)
    print(res,type(res),list(res))
    print("============主程序结束=============={}".format(datetime.datetime.now()))

运行结果:

============程序开始时间==============2022-07-08 11:04:00.576773这是第1个线程
============程序开始时间==============2022-07-08 11:04:00.576998这是第2个线程
============程序结束时间==============2022-07-08 11:04:00.577011这是第2个线程
============程序开始时间==============2022-07-08 11:04:00.577155这是第3个线程
============程序开始时间==============2022-07-08 11:04:00.577264这是第4个线程
============程序结束时间==============2022-07-08 11:04:00.577276这是第4个线程
============程序开始时间==============2022-07-08 11:04:00.577360这是第5个线程
============程序开始时间==============2022-07-08 11:04:00.577479这是第6个线程
============程序结束时间==============2022-07-08 11:04:00.577490这是第6个线程
============程序开始时间==============2022-07-08 11:04:00.577574这是第7个线程
============程序开始时间==============2022-07-08 11:04:00.577703这是第8个线程
============程序结束时间==============2022-07-08 11:04:00.577714这是第8个线程
============程序开始时间==============2022-07-08 11:04:00.577776这是第9个线程
============程序结束时间==============2022-07-08 11:04:01.578215这是第1个线程
============程序开始时间==============2022-07-08 11:04:01.578312这是第10个线程
============程序结束时间==============2022-07-08 11:04:01.578322这是第10个线程
============程序结束时间==============2022-07-08 11:04:01.578513这是第3个线程
============程序结束时间==============2022-07-08 11:04:01.578551这是第5个线程
============程序结束时间==============2022-07-08 11:04:01.578581这是第7个线程
============程序结束时间==============2022-07-08 11:04:01.578697这是第9个线程
<generator object Executor.map.<locals>.result_iterator at 0x7f32e0394f20> <class 'generator'> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
============主程序结束==============2022-07-08 11:04:01.578848

返回结果依旧是根据线程的顺序来的,很好
返回结果调用第二种方式:

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
def fn(res):
    print(res.result())
    return res.result()

if __name__=='__main__':
    result=[]
    with ThreadPoolExecutor(5) as t:
        for p in list(zip(L1,L2)):
            result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    print(result)
    print("============主程序结束=============={}".format(datetime.datetime.now()))

执行结果:

============程序开始时间==============2022-07-08 12:02:07.713207这是第1个线程
============程序开始时间==============2022-07-08 12:02:07.713511这是第2个线程
============程序结束时间==============2022-07-08 12:02:07.713525这是第2个线程
4
============程序开始时间==============2022-07-08 12:02:07.713625这是第3个线程
============程序开始时间==============2022-07-08 12:02:07.713739这是第4个线程
============程序结束时间==============2022-07-08 12:02:07.713751这是第4个线程
8
============程序开始时间==============2022-07-08 12:02:07.713844这是第5个线程
============程序开始时间==============2022-07-08 12:02:07.713927这是第6个线程
============程序结束时间==============2022-07-08 12:02:07.713974这是第6个线程
12
============程序开始时间==============2022-07-08 12:02:07.714068这是第7个线程
============程序开始时间==============2022-07-08 12:02:07.714195这是第8个线程
============程序结束时间==============2022-07-08 12:02:07.714206这是第8个线程
16
============程序开始时间==============2022-07-08 12:02:07.714277这是第9个线程
============程序结束时间==============2022-07-08 12:02:08.714232这是第1个线程
2
============程序开始时间==============2022-07-08 12:02:08.714339这是第10个线程
============程序结束时间==============2022-07-08 12:02:08.714350这是第10个线程
20
============程序结束时间==============2022-07-08 12:02:08.714556这是第3个线程
6
============程序结束时间==============2022-07-08 12:02:08.714605这是第5个线程
10
============程序结束时间==============2022-07-08 12:02:08.714646这是第7个线程
14
============程序结束时间==============2022-07-08 12:02:08.714819这是第9个线程
18
[None, None, None, None, None, None, None, None, None, None]
============主程序结束==============2022-07-08 12:02:08.714934

这个先后执行顺序不做保证,和Thread类似
本案例add使用了两个变量,迭代的时候需要使用lambda函数,然后在通过可变变量*的方式传入值,很神奇这种方法
返回结果调用第三种方法:

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
if __name__=='__main__':
    result=[]
    with ThreadPoolExecutor(5) as t:
        for p in list(zip(L1,L2)):
            result.append(t.submit(lambda p:add(*p),p))
    for i in result:
        print(i.result())
    print("============主程序结束=============={}".format(datetime.datetime.now()))

执行

============程序开始时间==============2022-07-08 12:59:50.259288这是第1个线程
============程序开始时间==============2022-07-08 12:59:50.259593这是第2个线程
============程序结束时间==============2022-07-08 12:59:50.259608这是第2个线程
============程序开始时间==============2022-07-08 12:59:50.259704这是第3个线程
============程序开始时间==============2022-07-08 12:59:50.259787这是第4个线程
============程序结束时间==============2022-07-08 12:59:50.259837这是第4个线程
============程序开始时间==============2022-07-08 12:59:50.259929这是第5个线程
============程序开始时间==============2022-07-08 12:59:50.260012这是第6个线程
============程序结束时间==============2022-07-08 12:59:50.260023这是第6个线程
============程序开始时间==============2022-07-08 12:59:50.260146这是第7个线程
============程序开始时间==============2022-07-08 12:59:50.260258这是第8个线程
============程序结束时间==============2022-07-08 12:59:50.260270这是第8个线程
============程序开始时间==============2022-07-08 12:59:50.260407这是第9个线程
============程序结束时间==============2022-07-08 12:59:51.260545这是第1个线程
============程序开始时间==============2022-07-08 12:59:51.260651这是第10个线程
============程序结束时间==============2022-07-08 12:59:51.260664这是第10个线程
============程序结束时间==============2022-07-08 12:59:51.260868这是第3个线程
============程序结束时间==============2022-07-08 12:59:51.260912这是第5个线程
============程序结束时间==============2022-07-08 12:59:51.260945这是第7个线程
============程序结束时间==============2022-07-08 12:59:51.261080这是第9个线程
2
4
6
8
10
12
14
16
18
20
============主程序结束==============2022-07-08 12:59:51.261224

使用了with方法默认要等线程执行完毕才能运行最下面的主程序结束
代码在改变下

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
def fn(res):
    print(res.result())
    return res.result()

if __name__=='__main__':
    # with ThreadPoolExecutor(5) as t:
    #     res=t.map(add,L1,L2)
    # print(res,type(res),list(res))
    # print("============主程序结束=============={}".format(datetime.datetime.now()))
    result=[]
    # with ThreadPoolExecutor(5) as t:
    #     for p in list(zip(L1,L2)):
    #         result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    # print(result)
    t=ThreadPoolExecutor(max_workers=5)
    for p in list(zip(L1, L2)):
        result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    # t.shutdown()
    print("============主程序结束=============={}".format(datetime.datetime.now()))

运行结果

============程序开始时间==============2022-07-08 12:15:02.978244这是第1个线程
============程序开始时间==============2022-07-08 12:15:02.978540这是第2个线程
============程序结束时间==============2022-07-08 12:15:02.978554这是第2个线程
4
============程序开始时间==============2022-07-08 12:15:02.978653这是第3个线程
============程序开始时间==============2022-07-08 12:15:02.978771这是第4个线程
============程序结束时间==============2022-07-08 12:15:02.978784这是第4个线程
8
============程序开始时间==============2022-07-08 12:15:02.978877这是第5个线程
============程序开始时间==============2022-07-08 12:15:02.978991这是第6个线程
============程序结束时间==============2022-07-08 12:15:02.979003这是第6个线程
12
============程序开始时间==============2022-07-08 12:15:02.979094这是第7个线程
============程序开始时间==============2022-07-08 12:15:02.979204这是第8个线程
============程序结束时间==============2022-07-08 12:15:02.979216这是第8个线程
16
============主程序结束==============2022-07-08 12:15:02.979256
============程序开始时间==============2022-07-08 12:15:02.979309这是第9个线程
============程序结束时间==============2022-07-08 12:15:03.979889这是第1个线程
2
============程序开始时间==============2022-07-08 12:15:03.980001这是第10个线程
============程序结束时间==============2022-07-08 12:15:03.980013这是第10个线程
20
============程序结束时间==============2022-07-08 12:15:03.980232这是第3个线程
6
============程序结束时间==============2022-07-08 12:15:03.980283这是第5个线程
10
============程序结束时间==============2022-07-08 12:15:03.980326这是第7个线程
14
============程序结束时间==============2022-07-08 12:15:03.980469这是第9个线程
18

注意下主程序结束==2022-07-08 12:15:02.979256 这个没有等线程结束就执行了,和只有start()没有join的一样,这种方式等着结束,需要这样写

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
def fn(res):
    print(res.result())
    return res.result()

if __name__=='__main__':
    # with ThreadPoolExecutor(5) as t:
    #     res=t.map(add,L1,L2)
    # print(res,type(res),list(res))
    # print("============主程序结束=============={}".format(datetime.datetime.now()))
    result=[]
    # with ThreadPoolExecutor(5) as t:
    #     for p in list(zip(L1,L2)):
    #         result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    # print(result)
    t=ThreadPoolExecutor(max_workers=5)
    for p in list(zip(L1, L2)):
        result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    t.shutdown()
    print("============主程序结束=============={}".format(datetime.datetime.now()))

运行结果

from concurrent.futures import  ThreadPoolExecutor
import  time,datetime
L1=[1,2,3,4,5,6,7,8,9,10]
L2=[1,2,3,4,5,6,7,8,9,10]
def add(a,b):
    print("============程序开始时间=============={}这是第{}个线程".format(datetime.datetime.now(),a))
    time.sleep(a%2)
    print("============程序结束时间=============={}这是第{}个线程".format(datetime.datetime.now(), a))
    return a+b
def fn(res):
    print(res.result())
    return res.result()

if __name__=='__main__':
    # with ThreadPoolExecutor(5) as t:
    #     res=t.map(add,L1,L2)
    # print(res,type(res),list(res))
    # print("============主程序结束=============={}".format(datetime.datetime.now()))
    result=[]
    # with ThreadPoolExecutor(5) as t:
    #     for p in list(zip(L1,L2)):
    #         result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    # print(result)
    t=ThreadPoolExecutor(max_workers=5)
    for p in list(zip(L1, L2)):
        result.append(t.submit(lambda p:add(*p),p).add_done_callback(fn))
    t.shutdown()
    print("============主程序结束=============={}".format(datetime.datetime.now()))
  • 技术无止境
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值