python学习 简单使用多进程、进程池来提高程序速度

最近爬取一个网站的数据,但是速度太慢了,所以想要利用多线程或者多进程的方式来爬取代码。

前言

翻阅了一下网上的资料,发现很多人对python多线程嗤之以鼻, 详情请点击这里 大概是说python的多线程不是真正意义上的多线程!因为python的解释器Cpython有一个叫做 **Global Interpreter Lock(全局解释器锁)**的东西,由于GIL锁存在,python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行)。

  • 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。 来源于维基百科

  • CPython 是用C语言实现的 Python 解释器。 作为官方实现,它是最广泛使用的 Python 解释器。

但是,python 的多线程并没有你想象的这么差,还有些大佬也提出了自己的看法,表示需要具体问题具体分析。

  1. 某乎专栏
  2. python3-cookbook

代码实现

多进程实现

# -*- coding:utf-8 -*-

"""
Process常用属性与方法:
    name:进程名
    pid:进程id
    run(),自定义子类时覆写
    start(),开启进程
    join(timeout=None),阻塞进程
    terminate(),终止进程
    is_alive(),判断进程是否存活
"""
from multiprocessing import Process
import os, time, random

def processfun(msg):
    t_start = time.time()
    print("%s开始执行,进程号为%d" % (msg,os.getpid()))
    time.sleep(random.random()*2)
    t_stop = time.time()
    print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))

def main():
    print("主进程执行中>>> pid={0}".format(os.getpid()))

    ps = []
    # 创建子进程实例
    for i in range(2):
        p = Process(target=processfun, name="worker" + str(i), args=(str(i)))
        ps.append(p)

    # 开启进程
    for i in range(2):
        ps[i].start()

    # 阻塞进程
    for i in range(2):
        ps[i].join()

    print("主进程终止")

if __name__ == '__main__':
    main()

进程池实现

from multiprocessing import Pool
import os, time, random


def processfun(msg):
    t_start = time.time()
    print("%s开始执行,进程号为%d" % (msg,os.getpid()))
    time.sleep(random.random()*2)
    t_stop = time.time()
    print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))

if __name__ == '__main__':
    po = Pool(3)  # 定义一个进程池,最大进程数3
    for i in range(0,10):
        po.apply_async(processfun,(i,))  # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
    po.close()  # 关闭进程池,关闭后po不再接收新的请求
    po.join()  # 等待po中所有子进程执行完成,再执行下面的代码,可以设置超时时间join(timeout=)

进程锁:

lock = multiprocessing.Lock() # 创建一个锁
lock.acquire() # 获取锁
lock.release() # 释放锁
with lock: # 自动帮你获取和释放锁

进程池的进程锁

from multiprocessing import Pool, Manager

lock = Manager().Lock() # 创建锁的方式不一样 其他都一样

进程间传递信息

mylist = multiprocessing.Manager().list(range(5))  # 主进程与子进程共享这个List

reference :

python3 进程池Pool 详解
Python多进程原理与实现
Python 进程之间共享数据(全局变量)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值