Python 简单并发的代码记录

简单介绍

近期想优化一下API的请求,顺带测试一下并发编程能快多少,用到进程、线程,顺带保留一些直接可用的简单的并发代码,方便后期复制粘贴

1、urllib3 网络请求

2、获取函数执行时间(大致的)

3、进程的简单实现

4、线程的简单实现

5、通过CPU计算以及网络IO请求,简单的对比性能上的差异

公共代码

python 复制代码
from datetime import datetime
import urllib3
import json

manager  = urllib3.PoolManager(num_pools=5)


def request_api(site):
    # print(site)
    test_url = 'http://127.0.0.1:9000/'
    r = manager.request('GET', test_url)
    data = r.data
    # json.loads(data)
    return data

def cpu_test(number):
    result = 235 * number
    return result

def print_time(func1, func2):
    start_time = datetime.now()
    func1(func2)
    end_time = datetime.now()
    print(func1, end_time-start_time)

线程测试 适合 IO密集型:读写

python 复制代码
from concurrent.futures import ThreadPoolExecutor

def thread_map_test(func):
    result = []
    site_list = range(1000)
    with ThreadPoolExecutor(max_workers=12) as executor:
        # 返回结果是一个迭代器
        ans = executor.map(func, site_list)
        for res in ans:
            result.append(res)
    return result

def thread_test(func):
    result = []
    site_list = range(1000)
    with ThreadPoolExecutor(max_workers=5) as executor:
            ans = [executor.submit(func, i) for i in site_list ]
            # as_completed(ans)
            for res in ans:
                result.append(res.result())

进程测试 适合CPU密集型:计算

python 复制代码
import multiprocessing

def process_by_map(func):
    data_list = range(1000)
    with multiprocessing.Pool(processes=4) as pool: 
        result = pool.map(func, data_list)
    return result 

# 会阻塞
def process_by_apply(func):
    result = []
    data_list = range(1000)
    with multiprocessing.Pool(processes=4) as pool: 
        for line in data_list:
            result.append(pool.apply(func, (line,)))
    return result

# 异步非阻塞
def process_by_apply_async(func):
    result = []
    data_list = range(1000)
    with multiprocessing.Pool(processes=4) as pool: 
        for line in data_list:
            result.append(pool.apply_async(func, (line,)))
    return result

综合测试

注意:多进程必须要写if name == 'main': 否则,IDE上面啥也不提示,但是没执行结果,直接点击执行就会提醒有异常

python 复制代码
# 请注意,多进程必须要写if __name__ == '__main__': 
if __name__ == '__main__':
    
    print('''计算测试 100万次计算''')
    
    # 0:00:00.362031
    print_time(process_by_map, cpu_test)
    # 0:01:48.696417
    print_time(process_by_apply, cpu_test)
    # 0:00:11.481112
    print_time(process_by_apply_async, cpu_test)
    # 0:00:25.352362
    print_time(thread_map_test, cpu_test)
    # 0:00:20.073205
    print_time(thread_test, cpu_test)
    
    print('''网络IO 测试  1000次请求''')
    # 0:00:04.105110
    print_time(process_by_map, request_api)
    # 0:00:07.180077
    print_time(process_by_apply, request_api)
    # 0:00:00.139999
    print_time(process_by_apply_async, request_api)
    # 0:00:02.757811
    print_time(thread_map_test, request_api)
    # 0:00:02.712561
    print_time(thread_test, request_api)

结果

1、网络IO 多线程或者进程的异步请求比较合适

2、CPU计算 多进程性能差异较大,用map应该是有一定的优化的

3、CPU 计算 多进程 map 快于 apply_async 快于 apply

4、网络IO apply_sync 异步 快于 map 快于 apply

其他

1、其他还有锁机制,还未测试

2、对于进程和线程的适用原因,不够清晰,进程上下文切换资源消耗较多,需要找时间了解一下

3、测试方式和写法还不太合理,记得起再优化吧

4、对于并发数,需要自行调整,具体如何科学的得到最优解,暂时也还没有研究,只是简单调试了一下

相关推荐
娅娅梨29 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥35 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾38 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺44 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
秀儿还能再秀1 小时前
机器学习——简单线性回归、逻辑回归
笔记·python·学习·机器学习
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
java—大象1 小时前
基于java+springboot+layui的流浪动物交流信息平台设计实现
java·开发语言·spring boot·layui·课程设计
yyqzjw2 小时前
【qt】控件篇(Enable|geometry)
开发语言·qt