12、爬虫之多进程

1 多进程

multiprocessing是python的多进程管理包,和threading.Thread类似

1.1 multiprocessing模块

直接从侧面用subprocesses替换线程使用GIL的方式,由于这一点,multiprocessing模块可以让程序员在给定的机器上充分的利用CPU。在multiprocessing中,通过创建Process对象生成进程,然后调用它的start()方法

from multiprocessing import Process

def func(name):
    print('hello', name)


if __name__ == "__main__":
    p = Process(target=func,args=('sxt',))
    p.start()
    p.join()  # 等待进程执行完毕

1.2 Manager类,实现数据共享

在使用并发设计的时候最好尽可能的避免共享数据,尤其是在使用多进程的时候。 如果你真有需要 要共享数据,可以使用由Manager()返回的manager提供list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array类型的支持

from multiprocessing import Process,Manager,Lock


def print_num(info_queue,l,lo):
    with lo:
        for n in l:
            info_queue.put(n)

def updata_num(info_queue,lo):
    with lo:
        while not info_queue.empty():
            print(info_queue.get())


if __name__ == '__main__':
        manager = Manager()
        into_html = manager.Queue()
        lock = Lock()
        a = [1, 2, 3, 4, 5]
        b = [11, 12, 13, 14, 15]

        p1 = Process(target=print_num,args=(into_html,a,lock))
        p1.start()
        p2 = Process(target=print_num,args=(into_html,b,lock))
        p2.start()
        p3 = Process(target=updata_num,args=(into_html,lock))
        p3.start()
        p1.join()
        p2.join()
        p3.join()

1.3 进程池的使用

  • 进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
  • 进程池中有两个方法:
    • apply同步执行-串行
    • apply_async异步执行-并行
from multiprocessing import Pool,Manager
def print_num(info_queue,l):
    for n in l:
        info_queue.put(n)

def updata_num(info_queue):
    while not info_queue.empty():
        print(info_queue.get())

if __name__ == '__main__':
    html_queue =Manager().Queue()
    a=[11,12,13,14,15]
    b=[1,2,3,4,5]
    pool = Pool(3)
    pool.apply_async(func=print_num,args=(html_queue,a))
    pool.apply_async(func=print_num,args=(html_queue,b))
    pool.apply_async(func=updata_num,args=(html_queue,))
    pool.close() #这里join一定是在close之后,且必须要加join,否则主进程不等待创建的子进程执行完毕
    pool.join() # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭

posted @ 2022-02-26 19:38  齐天_大圣  阅读(67)  评论(0)    收藏  举报