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

相关推荐
黎子越16 小时前
python循环相关联系
开发语言·python·算法
安然无虞16 小时前
「正则表达式」精讲
开发语言·测试工具·正则表达式
csbysj202016 小时前
DOM 解析器错误
开发语言
Дерек的学习记录16 小时前
二叉树(下)
c语言·开发语言·数据结构·学习·算法·链表
葡萄成熟时 !16 小时前
JDK时间类
java·开发语言
气派飞鹰16 小时前
windows下C++个人开发最佳实践(CMake+vcpkg+trae)
开发语言·c++·个人开发
余瑜鱼鱼鱼16 小时前
Thread类中run和start的区别
java·开发语言·前端
n 55!w !10816 小时前
js练习作业
开发语言·javascript·ecmascript
Whisper_Sy16 小时前
Flutter for OpenHarmony移动数据使用监管助手App实战 - 月报告实现
android·开发语言·javascript·网络·flutter·ecmascript
灰灰勇闯IT16 小时前
【Flutter for OpenHarmonyDart 入门日记】第5篇:字典类型 Map 与动态类型 dynamic 全解析
开发语言·javascript·ecmascript