python 多进程与多线程

        由于python GIL的存在,让python 多线程很鸡肋,很多时候如果有并发的需求,则选择多进程来实现,但是多进程是很消耗资源的,而且进程之间不能资源共享,而且还会受到机器CPU核心数目的限制,因此在特定场景下针对不同需求会有一些取舍。传闻对于IO密集性的操作,比如,处理多个http 的请求,其实python多线程是完全可以发挥作用的,这种方式比多进程要高效的多(还好有高级python开发的好基友指点,不然一直认为python多线程就是废材,真外行了,在此贴出他的私人博客 https://www.longxyun.com/ )。为了验证这一伟大结论,特此设计一个对比实验

  • 创建一个简单Flask服务
import time
from flask import Flask

app = Flask(__name__)


@app.route("/", methods=["GET"])
def func():
    time.sleep(2)  # 模拟服务需要2秒后响应过程
    return "GET"


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5555)
  • 多线程访问脚本
import time
import requests
from threading import Thread

url = "http://127.0.0.1:5555/"

res_list = []
t_list = []


def func(x):
    print("Thread: {}".format(x))
    res_list.append(requests.get(url))


if __name__ == '__main__':
    # 开启10个线程
    s = time.time()
    for i in range(10):
        t = Thread(target=func, args=(i,))
        t_list.append(t)
        t.start()
    for t in t_list:
        t.join()
    print("MAIN processing")
    for r in res_list:
        print(r.text)
    print(time.time() - s)
  • 多进程访问脚本
import time
import requests
from multiprocessing.pool import Pool


url = "http://127.0.0.1:5555/"


def func(x):
    print("Processing: {}".format(x))
    return requests.get(url)


if __name__ == '__main__':
    s = time.time()
    p = Pool()
    res = p.map(func, [i for i in range(10)])
    p.close()
    p.join()
    print("MAIN processing")
    for r in res:
        print(r.text)
    print(time.time() - s)
  • 运行结果

       如图所示,当启动多个请求数目大于CPU核数时(我本机是4核心),多线程消耗时间明显好于多进程,因为本身是IO操作,没有高强度计算,也不会连续使用CPU,仅仅是一个指令的触发操作,因此在请求这个指令触发一瞬间,执行过程已经交给网络传输了,而与此同时线程已经切换到了下一个线程,所以当把启动线程增加到100个时候,时间依旧会接近2秒,因为线程切换也会有开销,所以不可能完全等于2秒。

       综上所述,实践是检验真理的唯一标准!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值