异步【ThreadPoolExecutor】和【ProcessPoolExecutor】实例

原因:
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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值