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
.map..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个线程
.map..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()))