VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • PythonI/O进阶学习笔记_10.python的多线程(4)

3 successed! 3 2
复制代码
为什么done()输出的是false呢。因为submit的返回是非阻塞的,没有等task执行完就返回了task done的状态。
如果隔几秒输出done()的返回又是true了。
 
Future对象常用的其他方法:cancel()
取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True。
复制代码
print(task1.done())
print(task1.cancel())
print(task2.done())

#result 是阻塞的,接受函数的返回
print(task1.result())

print(task2.result())

output:
False
False
False
get html page 2 successed!
get html page 3 successed!
3
2
复制代码

cancelled():返回 Future 代表的线程任务是否被成功取消。

 
2.获取所有完成的future的状态和值as_completed和map
 
2.1 .as_complete
复制代码
from concurrent.futures import  ThreadPoolExecutor,as_completed
import time
 
def get_html(uid):
    time.sleep(uid)
    url="www.test.com/{}".format(uid)
    print("get url successed: \" {} \"".format(url))
    return uid
excutor=ThreadPoolExecutor(max_workers=2)
uids=[5,2,3]
future_list=[ excutor.submit(get_html,(uid)) for uid in uids]
for future in as_completed(future_list):
    print(future.result())
 
#output:
get url successed: " www.test.com/2 "
2
get url successed: " www.test.com/5 "
5
get url successed: " www.test.com/3 "
3
复制代码

as_completed():yield 所有完成的futures的所有返回。

那么as_complete是如何做到收集所有完成的异步方法的状态的呢?

先把所有已经是finish状态的future返回,
再一直while pending,等待timeout范围内的future变成finish,把finish的future yield出来。
复制代码
from concurrent.futures import  ThreadPoolExecutor,as_completed
import time
 
def get_html(uid):
    time.sleep(uid)
    url="www.test.com/{}".format(uid)
    print("get url successed: \" {} \"".format(url))
    return uid
excutor=ThreadPoolExecutor(max_workers=2)
uids=[5,2,3]
future_list=[ excutor.submit(get_html,(uid)) for uid in uids]
for future in as_completed(future_list):
    print(future.result())
 
#output:
get url successed: " www.test.com/2 "
2
get url successed: " www.test.com/5 "
5
get url successed: " www.test.com/3 "
3
复制代码
 
2.2  通过excutor的map方法 获取已经完成的future
excutor的map,和map是差不多的,传递函数和参数列表,就会多多线程运行参数列表数的线程。
与a中不一样的是,map返回的顺序和url中的顺序是一样的,而a的as_completed是谁先finishi谁就先被yield出来。
而且map返回的就是result,而as_completed返回的是Future。
复制代码
from concurrent.futures import  ThreadPoolExecutor,as_completed,wait
import time
def get_html(uid):
    time.sleep(uid)
    url="www.test.com/{}".format(uid)
    print("get url successed: \" {} \"".format(url))
    return uid
 
excutor=ThreadPoolExecutor(max_workers=2)
uids=[5,2,3]
 
result_list=excutor.map(get_html,uids)
for result in result_list:
    print(result)
 
#output:
get url successed: " www.test.com/2 "
get url successed: " www.test.com/5 "
5
2
get url successed: " www.test.com/3 "
3
复制代码

 

3.wait()方法
wait方法用于阻塞,指定某一个task或者一些task执行完成再往下执行。
def wait(fs, timeout=None, return_when=ALL_COMPLETED)
例:如果我想在全部task执行完之后打印"task end"字符串
复制代码
from concurrent.futures import  ThreadPoolExecutor,as_completed,wait
import time
def get_html(uid):
    time.sleep(uid)
    url="www.test.com/{}".format(uid)
    print("get url successed: \" {} \"".format(url))
    return uid
excutor=ThreadPoolExecutor(max_workers=2)
uids=[5,2,3]
future_list=[ excutor.submit(get_html,(uid)) for uid in uids]
print("task end")
 
#output:
task end
get url successed: " www.test.com/2 "
get url successed: " www.test.com/5 "
get url successed: " www.test.com/3 "

#还没有执行完,就输出了 task end。需要加上:
wait(future_list)
print("task end")
 
#output:
get url successed: " www.test.com/2 "
get url successed: " www.test.com/5 "
get url successed: " www.test.com/3 "
task end
复制代码
wait还可以指定在什么时候执行完后返回。