原因:
concurrent.futures模块提供了高度封装的异步调用接口
ThreadPoolExecutor:线程池,提供异步调用
ProcessPoolExecutor: 进程池,提供异步调用
1.简单ProcessPoolExecutor: 进程池
# coding=utf-8
# 用法
import logging
from concurrent.futures import ProcessPoolExecutor
import os, time, random
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(processName)s %(message)s"
)
def task (n):
logging.info('%s is runing' % os.getpid())
time.sleep(random.randint(1, 3))
return n ** 2
if __name__ == '__main__':
start = time.time()
executor = ProcessPoolExecutor(max_workers=3)
futures = []
for i in range(11):
future = executor.submit(task, i)
futures.append(future)
for future in futures:
logging.info(future.result())
executor.shutdown(True)
logging.info(time.time() - start)
输出:
2019-10-07 20:27:25,089 [*] SpawnProcess-2 8168 is runing
2019-10-07 20:27:25,090 [*] SpawnProcess-1 4764 is runing
2019-10-07 20:27:25,095 [*] SpawnProcess-3 4368 is runing
2019-10-07 20:27:26,095 [*] SpawnProcess-3 4368 is runing
2019-10-07 20:27:27,090 [*] SpawnProcess-1 4764 is runing
2019-10-07 20:27:28,090 [*] SpawnProcess-2 8168 is runing
2019-10-07 20:27:28,091 [*] MainProcess 0
2019-10-07 20:27:28,092 [*] MainProcess 1
2019-10-07 20:27:28,092 [*] SpawnProcess-1 4764 is runing
2019-10-07 20:27:28,092 [*] MainProcess 4
2019-10-07 20:27:29,095 [*] SpawnProcess-3 4368 is runing
2019-10-07 20:27:29,095 [*] MainProcess 9
2019-10-07 20:27:29,095 [*] MainProcess 16
2019-10-07 20:27:31,094 [*] SpawnProcess-2 8168 is runing
2019-10-07 20:27:31,094 [*] SpawnProcess-1 4764 is runing
2019-10-07 20:27:31,095 [*] MainProcess 25
2019-10-07 20:27:31,096 [*] MainProcess 36
2019-10-07 20:27:31,096 [*] SpawnProcess-3 4368 is runing
2019-10-07 20:27:31,097 [*] MainProcess 49
2019-10-07 20:27:32,096 [*] MainProcess 64
2019-10-07 20:27:33,095 [*] MainProcess 81
2019-10-07 20:27:34,097 [*] MainProcess 100
2019-10-07 20:27:34,122 [*] MainProcess 9.143441438674927
2.简单ThreadPoolExecutor:线程池
# coding=utf-8
# 用法
import logging
from concurrent.futures import ThreadPoolExecutor
import os, time, random
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(processName)s %(threadName)s %(message)s"
)
def task (n):
logging.info('%s is runing' % os.getpid())
time.sleep(random.randint(1, 3))
return n ** 2
if __name__ == '__main__':
start = time.time()
executor = ThreadPoolExecutor(max_workers=3)
futures = []
for i in range(11):
future = executor.submit(task, i)
futures.append(future)
for future in futures:
logging.info(future.result())
executor.shutdown(True)
logging.info(time.time() - start)
输出:
2019-10-07 20:27:53,067 [*] MainProcess ThreadPoolExecutor-0_0 5036 is runing
2019-10-07 20:27:53,067 [*] MainProcess ThreadPoolExecutor-0_1 5036 is runing
2019-10-07 20:27:53,067 [*] MainProcess ThreadPoolExecutor-0_2 5036 is runing
2019-10-07 20:27:54,084 [*] MainProcess ThreadPoolExecutor-0_2 5036 is runing
2019-10-07 20:27:55,085 [*] MainProcess ThreadPoolExecutor-0_1 5036 is runing
2019-10-07 20:27:55,085 [*] MainProcess ThreadPoolExecutor-0_2 5036 is runing
2019-10-07 20:27:56,079 [*] MainProcess ThreadPoolExecutor-0_0 5036 is runing
2019-10-07 20:27:56,079 [*] MainProcess MainThread 0
2019-10-07 20:27:56,080 [*] MainProcess MainThread 1
2019-10-07 20:27:56,080 [*] MainProcess MainThread 4
2019-10-07 20:27:56,081 [*] MainProcess MainThread 9
2019-10-07 20:27:57,087 [*] MainProcess ThreadPoolExecutor-0_1 5036 is runing
2019-10-07 20:27:57,087 [*] MainProcess MainThread 16
2019-10-07 20:27:58,080 [*] MainProcess ThreadPoolExecutor-0_0 5036 is runing
2019-10-07 20:27:58,087 [*] MainProcess ThreadPoolExecutor-0_2 5036 is runing
2019-10-07 20:27:58,088 [*] MainProcess MainThread 25
2019-10-07 20:27:58,088 [*] MainProcess MainThread 36
2019-10-07 20:27:59,089 [*] MainProcess ThreadPoolExecutor-0_2 5036 is runing
2019-10-07 20:28:00,089 [*] MainProcess MainThread 49
2019-10-07 20:28:01,081 [*] MainProcess MainThread 64
2019-10-07 20:28:01,081 [*] MainProcess MainThread 81
2019-10-07 20:28:01,090 [*] MainProcess MainThread 100
2019-10-07 20:28:01,091 [*] MainProcess MainThread 8.02418041229248
3.ProcessPoolExecutor: 进程池map的用法
# coding=utf-8
# 用法
import logging
from concurrent.futures import ProcessPoolExecutor
import os, time, random
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(processName)s %(message)s"
)
def task (n):
logging.info('%s is runing' % os.getpid())
time.sleep(random.randint(1, 3))
return n ** 2
if __name__ == '__main__':
start = time.time()
executor = ProcessPoolExecutor(max_workers=3)
# map-------------------------------------
futures = executor.map(task, range(1, 12))
for future in futures:
logging.info(future)
executor.shutdown(True)
logging.info(time.time() - start)
输出:
2019-10-07 20:33:39,853 [*] SpawnProcess-1 276 is runing
2019-10-07 20:33:39,854 [*] SpawnProcess-2 3420 is runing
2019-10-07 20:33:39,855 [*] SpawnProcess-3 9192 is runing
2019-10-07 20:33:41,855 [*] SpawnProcess-2 3420 is runing
2019-10-07 20:33:41,856 [*] SpawnProcess-3 9192 is runing
2019-10-07 20:33:42,860 [*] SpawnProcess-2 3420 is runing
2019-10-07 20:33:42,860 [*] SpawnProcess-3 9192 is runing
2019-10-07 20:33:42,860 [*] SpawnProcess-1 276 is runing
2019-10-07 20:33:42,860 [*] MainProcess 1
2019-10-07 20:33:42,860 [*] MainProcess 4
2019-10-07 20:33:42,860 [*] MainProcess 9
2019-10-07 20:33:42,860 [*] MainProcess 16
2019-10-07 20:33:42,860 [*] MainProcess 25
2019-10-07 20:33:43,862 [*] SpawnProcess-2 3420 is runing
2019-10-07 20:33:43,862 [*] SpawnProcess-1 276 is runing
2019-10-07 20:33:43,862 [*] MainProcess 36
2019-10-07 20:33:44,863 [*] SpawnProcess-2 3420 is runing
2019-10-07 20:33:45,862 [*] MainProcess 49
2019-10-07 20:33:45,863 [*] MainProcess 64
2019-10-07 20:33:45,863 [*] MainProcess 81
2019-10-07 20:33:45,865 [*] MainProcess 100
2019-10-07 20:33:46,864 [*] MainProcess 121
2019-10-07 20:33:46,890 [*] MainProcess 7.154351472854614
4.ThreadPoolExecutor:线程池 map的用法
# coding=utf-8
# 用法
import logging
from concurrent.futures import ThreadPoolExecutor
import os, time, random
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(threadName)s %(message)s"
)
def task (n):
logging.info('%s is runing' % os.getpid())
time.sleep(random.randint(1, 3))
return n ** 2
if __name__ == '__main__':
start = time.time()
executor = ThreadPoolExecutor(max_workers=3)
# map---------------------------------------
futures = executor.map(task, range(1, 12))
for future in futures:
logging.info(future)
logging.info(time.time() - start)
输出:
2019-10-07 20:36:01,895 [*] ThreadPoolExecutor-0_0 8228 is runing
2019-10-07 20:36:01,895 [*] ThreadPoolExecutor-0_1 8228 is runing
2019-10-07 20:36:01,896 [*] ThreadPoolExecutor-0_2 8228 is runing
2019-10-07 20:36:02,903 [*] ThreadPoolExecutor-0_0 8228 is runing
2019-10-07 20:36:02,904 [*] MainThread 1
2019-10-07 20:36:03,903 [*] ThreadPoolExecutor-0_2 8228 is runing
2019-10-07 20:36:03,903 [*] ThreadPoolExecutor-0_1 8228 is runing
2019-10-07 20:36:03,904 [*] MainThread 4
2019-10-07 20:36:03,904 [*] MainThread 9
2019-10-07 20:36:03,925 [*] ThreadPoolExecutor-0_0 8228 is runing
2019-10-07 20:36:03,925 [*] MainThread 16
2019-10-07 20:36:04,927 [*] ThreadPoolExecutor-0_0 8228 is runing
2019-10-07 20:36:05,929 [*] ThreadPoolExecutor-0_0 8228 is runing
2019-10-07 20:36:06,909 [*] ThreadPoolExecutor-0_1 8228 is runing
2019-10-07 20:36:06,909 [*] ThreadPoolExecutor-0_2 8228 is runing
2019-10-07 20:36:06,910 [*] MainThread 25
2019-10-07 20:36:06,910 [*] MainThread 36
2019-10-07 20:36:06,910 [*] MainThread 49
2019-10-07 20:36:06,910 [*] MainThread 64
2019-10-07 20:36:08,934 [*] MainThread 81
2019-10-07 20:36:08,934 [*] MainThread 100
2019-10-07 20:36:08,934 [*] MainThread 121
2019-10-07 20:36:08,934 [*] MainThread 7.039489984512329
5.ProcessPoolExecutor: 进程池回调函数
# coding=utf-8
import logging
from concurrent.futures import ProcessPoolExecutor
import os, time
import requests
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(processName)s %(message)s"
)
def get_page (url):
logging.info(f"<进程ID:{os.getpid()}> get:{url}")
response = requests.get(url)
if response.status_code == 200:
return {'url': url, 'text': response.text}
def parse_page (res):
res = res.result()
url = res['url']
size = len(res['text'])
logging.info(f"<进程ID:{os.getpid()}> parse:{url} size:{size}")
parse_res = f"url:<{url}> size:<{size}>\n"
with open('db.txt', 'a', encoding="utf-8") as f:
f.write(parse_res)
if __name__ == '__main__':
start = time.time()
urls = [
'https://www.baidu.com',
'https://www.python.org',
'https://www.openstack.org',
'https://help.github.com/',
'http://www.sina.com.cn/'
]
executor = ProcessPoolExecutor(max_workers=3)
# 异步提交任务------------------------------------------------------------
futures = []
for url in urls:
future = executor.submit(get_page, url).add_done_callback(parse_page)
futures.append(future)
executor.shutdown(True)
logging.info(time.time() - start)
输出:
2019-10-07 20:53:45,947 [*] SpawnProcess-2 <进程ID:3300> get:https://www.baidu.com
2019-10-07 20:53:45,947 [*] SpawnProcess-1 <进程ID:6116> get:https://www.python.org
2019-10-07 20:53:45,955 [*] SpawnProcess-3 <进程ID:8144> get:https://www.openstack.org
2019-10-07 20:53:46,074 [*] SpawnProcess-2 <进程ID:3300> get:https://help.github.com/
2019-10-07 20:53:46,075 [*] MainProcess <进程ID:9156> parse:https://www.baidu.com size:2443
2019-10-07 20:53:49,089 [*] SpawnProcess-3 <进程ID:8144> get:http://www.sina.com.cn/
2019-10-07 20:53:49,089 [*] MainProcess <进程ID:9156> parse:https://www.openstack.org size:60746
2019-10-07 20:53:49,295 [*] MainProcess <进程ID:9156> parse:https://www.python.org size:48847
2019-10-07 20:53:49,781 [*] MainProcess <进程ID:9156> parse:http://www.sina.com.cn/ size:547095
2019-10-07 20:53:50,436 [*] MainProcess <进程ID:9156> parse:https://help.github.com/ size:156719
2019-10-07 20:53:50,488 [*] MainProcess 4.833276033401489
6.ThreadPoolExecutor:线程池回调函数
# coding=utf-8
import logging
from concurrent.futures import ThreadPoolExecutor
import os, time
import requests
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [*] %(threadName)s %(message)s"
)
def get_page (url):
logging.info(f"<进程ID:{os.getpid()}> get:{url}")
response = requests.get(url)
if response.status_code == 200:
return {'url': url, 'text': response.text}
def parse_page (res):
res = res.result()
url = res['url']
size = len(res['text'])
logging.info(f"<进程ID:{os.getpid()}> parse:{url} size:{size}")
parse_res = f"url:<{url}> size:<{size}>\n"
with open('db.txt', 'a', encoding="utf-8") as f:
f.write(parse_res)
if __name__ == '__main__':
start = time.time()
urls = [
'https://www.baidu.com',
'https://www.python.org',
'https://www.openstack.org',
'https://help.github.com/',
'http://www.sina.com.cn/'
]
executor = ThreadPoolExecutor(max_workers=3)
# 异步提交任务------------------------------------------------------------
futures = []
for url in urls:
future = executor.submit(get_page, url).add_done_callback(parse_page)
futures.append(future)
executor.shutdown(True)
logging.info(time.time() - start)
输出:
2019-10-07 20:57:20,323 [*] ThreadPoolExecutor-0_0 <进程ID:2956> get:https://www.baidu.com
2019-10-07 20:57:20,323 [*] ThreadPoolExecutor-0_1 <进程ID:2956> get:https://www.python.org
2019-10-07 20:57:20,324 [*] ThreadPoolExecutor-0_2 <进程ID:2956> get:https://www.openstack.org
2019-10-07 20:57:20,460 [*] ThreadPoolExecutor-0_0 <进程ID:2956> parse:https://www.baidu.com size:2443
2019-10-07 20:57:20,460 [*] ThreadPoolExecutor-0_0 <进程ID:2956> get:https://help.github.com/
2019-10-07 20:57:21,169 [*] ThreadPoolExecutor-0_2 <进程ID:2956> parse:https://www.openstack.org size:60746
2019-10-07 20:57:21,171 [*] ThreadPoolExecutor-0_2 <进程ID:2956> get:http://www.sina.com.cn/
2019-10-07 20:57:21,587 [*] ThreadPoolExecutor-0_2 <进程ID:2956> parse:http://www.sina.com.cn/ size:547095
2019-10-07 20:57:21,736 [*] ThreadPoolExecutor-0_0 <进程ID:2956> parse:https://help.github.com/ size:156719
2019-10-07 20:57:23,799 [*] ThreadPoolExecutor-0_1 <进程ID:2956> parse:https://www.python.org size:48847
2019-10-07 20:57:23,799 [*] MainThread 3.4770350456237793