• 『Python』多进程处理


    尝试学习python的多进程模组,对比多线程,大概的区别在:

      1.多进程的处理速度更快

      2.多进程的各个子进程之间交换数据很不方便

    多进程调用方式

      进程基本使用multicore()

      进程池优化进程的调用multicore_pool(),在使用进程池的时候,运许函数有return,而基本用法中进程是接收不了return的

      进程队列用法,大部分方法和python的基本队列是一致的,

    q=mp.Queue() 声明
    q.put() 添加
    q.get() 释放
    q.empty() 判断是不是空的

    """
    Created on Tue Dec  5 09:00:00 2017
    
    @author: hellcat
    """
    
    import time
    import numpy as np
    import threading as td
    import multiprocessing as mp
    
    def job(q):
        for i in range(3):
            q.put(i)
        
    def multicore():
        q=mp.Queue()
        ps = [mp.Process(target=job,args=(q,)),
             mp.Process(target=job,args=(q,))]  # 基本的子进程创建方法
        for p in ps:
            p.start()
            
        time.sleep(3)
        
        for p in ps:
            p.join()                            # 需要协调结束
            
        while True:
            if q.empty() != True:
                print(q.get())
            else:
                break
    
    def multithread():  
        q=mp.Queue()
        ps = [td.Thread(target=job,args=(q,)),
             td.Thread(target=job,args=(q,))]  # 基本的子线程创建方法
        for p in ps:
            p.start()
            
        time.sleep(3)
        
        for p in ps:
            p.join()
            
        while True:
            if q.empty() != True:
                print(q.get())
            else:
                break
    
    def job_pool(q):
        res0 = 0
        for i in range(np.random.randint(10)):
            res0 += i**3
        return res0
    
    def multicore_pool():
        pool = mp.Pool(processes=2)                                  # 初始化进程池,可以指定进程数
        res1 = pool.map(job_pool,range(20))                          # map方法在线程池中同时添加多个线程
        print(res1)                              # 返回值为函数的return
        res2 = [pool.apply_async(job_pool,(i,)) for i in range(20)]  # 在进程池中单个添加进程
        print([res.get() for res in res2])                           # 注意此时每个进程的返回并不直接是return,需要get方法得到的才是return
        # for res in res2:
        #     print(res.get())
        
    if __name__=='__main__':
        # multicore()
        # multithread()
        multicore_pool()
    

     进程共享变量 & 进程锁

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    """
    Created on Tue Dec  5 10:15:58 2017
    
    @author: hellcat
    """
    
    import time
    import multiprocessing as mp
    
    def job(v,num,l):  # 需要把共享变量实例作为参数传入才行
        l.acquire()  # 进程锁锁住
        for _ in range(10):
            time.sleep(0.1)
            v.value += num # 获取共享变量的值,并进行操作
            print(v.value)
        l.release()  # 进程锁释放
    
    def muticore():
        l = mp.Lock()  # 实例化进程锁
        v = mp.Value('i',0)  # 实例化共享变量
        # p = mp.Pool(processes=2)
        
        # p.map(job,((v,1,l),(v,3,l)))
        p1 = mp.Process(target=job,args=(v,1,l))
        p2 = mp.Process(target=job,args=(v,3,l))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
        
    if __name__=='__main__':
        muticore()
    

      不同于多线程使用全局变量就可以以共享变量,多进程必须使用 v = mp.Value('i',0)这样的语句声明变量(其实还可以是mp.Array('i',[1,2,3]),注意,这里只能是1维的list,[[1,2]]这样都是不可以的),并将v作为参数传给函数,在函数内部使用的时候也需要使用v.value来唤醒其值。

      进程锁会在锁住时阻止其他进程使用共享变量,所以可以看到输出中先执行了10次+1,然后执行了10次+3,而不使用进程锁+1和+3会无规律的交替进行:

    注释掉进程锁:

    1
    4
    5
    8
    9
    12
    13
    16
    17
    20
    21
    24
    25
    28
    29
    32
    33
    36
    37
    40

    使用进程锁(上面代码没有注释掉进程锁):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    13
    16
    19
    22
    25
    28
    31
    34
    37
    40

  • 相关阅读:
    SEO优化技巧:16个方法优化网页中的图片
    《Google官方SEO指南》十一:以恰当的方式推广你的网站
    ASP.NET Eval如何进行数据绑定
    浅析ASP.NET页面缓存的几点体会
    浅谈ADO.NET中的五个主要对象
    WCF 入门 WCF基础知识问与答
    Hibernate第一次课(1)
    谷歌、雅虎支持中文域名搜索 有助提升SEO
    告诉SEO初学者:百度收录并非终极目标
    WF 创建 SQL 持久性数据库
  • 原文地址:https://www.cnblogs.com/hellcat/p/7985694.html
Copyright © 2020-2023  润新知