• python 多进程


    什么是进程

    参考任务管理器,所有任务都是进程

    线程包含在进程之内。

     

    一个程序运行起来后,代码 + 用到的资源称之为进程

    它是操作系统分配资源的基本单元。

    不仅可以通过线程完成多任务,进程同样也可以做到。

    进程的状态

    工作中,任务数往往大于cpu的核心数。即,一定会有一些任务在执行,而另一些在等待cpu进行执行,因此产生了不同的状态。

    就绪状态

    运行条件都已满足,在等待cpu执行

    执行状态

    cpu正在执行其功能

    等待状态

    等待满足某些条件,例如一个程序sleep了,此时就处于等待状态

     

    多进程

    多进程可以做到并行,而多线程不行

    multiprocessing模块

    使用多进程要用到该模块。

    Process 创建参数设置

    target 如果传递了函数的引用,可以创建进程任务

    args 给target指定的函数传递的参数,元祖的方式传参数

    kwargs 给target指定的函数命名传参

    name 给进程设定一个名字,可以不设置

    group 指定进程组,到时候用不到

     

    process 创建实例对象的常用方法

    start() 启动,创建子进程

    is_alive() 判断进程是否存活

    join(timeout) 是否等待子进程执行结束,或者等待多少秒

    terminate() 不管任务是否完成逻辑终止子进程

    代码实例

     1 from multiprocessing import Process
     2 import time
     3 num =100
     4 
     5 def work1():
     6    for i in range(10):
     7       global  num
     8       print(F"这个是任务1------{num}")
     9       num += 1
    10       time.sleep(0.5)
    11 def work2():
    12    for i in range(10):
    13       global num
    14       print(F"这个是任务2------{num}")
    15       num += 1
    16       time.sleep(0.5)
    17 # 创建两个进程
    18 if __name__ == '__main__':
    19    # 进程执行的时候不加 __name__ == main 会报错
    20    # 原因是什么呢?
    21    # 如果没有main ,代码会相当于,从模块导入,会陷入无限递归的状态
    22    # 进程之间的资源是独立的, windows下面会报错, linux mac 不会
    23    # 全局变量不进行共享,不会造成数据不安全之类的问题
    24    p1 = Process(target=work1)
    25    p2 = Process(target=work2)
    26    p1.start()
    27    p2.start()

    个人理解

    运行一个进程的时候,系统会划分出来一块内存,存储这个进程的相关资源

    属于该进程的线程是会使用进程的相关资源的,在进程的内存块中划出小块内存支持线程运行。

    进程间全局变量则不共享,原因是因为使用的并非是同一块内存地址。

     

    进程,线程之间的区别联系

    线程存在于进程之中

    进程间存在于不同的内存地址中,进程之间全局变量不共享。

    那么如果想要共享,实现进程间的通讯问题。

    则需要使用到多进程模块下的队列。

     

    前面学到的queue模块,虽然是线程安全的,但不适用于多进程

    需要使用的事multiprocessing下的Queue模块

    量模块在内置方法上没什么区别,但是多进程中的queue更为强大、。

     

    区别为Queue是各子进程私有,multiprocessing.Queue是各子进程共有。

    看一下代码实例

    def work1(q):
       while True:
          if q.qsize() > 0 :
             url = q.get()
             requests.get(url)
             print("work1 正在执行任务----")
    def work2(q):
       while True:
          if q.qsize() > 0:
             url = q.get()
             requests.get(url)
             print("work2 正在执行任务----")
    if __name__ == '__main__':
       # 进程执行的时候不加 __name__ == main 会报错
       # 原因是什么呢?
       # 如果没有main ,代码会相当于,从模块导入,会陷入无限递归的状态
       # 进程之间的资源是独立的, windows下面会报错, linux mac 不会
       # 全局变量不进行共享,不会造成数据不安全之类的问题
    
       # 注意!!! 如果吧队列放到全局变量中,就依然不会行程进程之间资源共享
       # 原因跟之前没有加main是一样的,
       q =Queue()
       # 通过多进程下面的queue,然后穿参数进去,然后进程之间共同享有queue资源
       for i in range(10):
          q.put("http://www.baidu.com")
       p1 = Process(target=work1,args=(q,))
       p2 = Process(target=work2,args=(q,))
       p1.start()
       p2.start()

    进程池子

    当需要创新的子进程数量不多时,利用multiprocessing中的process动态生成多个线程。

    但是如果上百甚至上千个目标,手动去创建进程的工作量太大。

    此时可以使用multiprocessing模块提供的pool方法。

     

    初始化pool时,可以指定一个最大的进程数,当有新的请求提交到pool中时

    如果池子还没满,那么就会创建一个新的进程用来执行该请求,

    但是如果进程池内数量已达到最大,

    那么请求就会等待,等到池中有进程结束,才会用之前的进程来执行新任务。

    pool的方法

     1 apply_async() 使用非租塞方式调用func
     2 close() 关闭pool
     3 terminate() 不管任务是否完成立即终止
     4 join() 主进程阻塞,等待子进程的退出,必须在close或terminate之后使用
     5 import os
     6 import time
     7 from multiprocessing import Process,Queue,Manager,Pool
     8 def work1():
     9   print("进程池---{}".format(os.getpid()))
    10   time.sleep(1)
    11 if __name__ == '__main__':
    12 p = Pool(3)
    13 for i in range(10):
    14   p.apply_async(work1)
    15 
    16 p.close()
    17 p.join()

    pool中的queue

    如果使用pool创建进程,就需要用multiprocessing,manager()中的queue()

     1 例子:
     2 import os
     3 import time
     4 from multiprocessing import Pool,Manager
     5 
     6 def work1(q):
     7   print("进程池---{}".format(os.getpid()))
     8   print(q.get())
     9   time.sleep(1)
    10 if __name__ == '__main__':
    11 Manager()
    12 q = Manager().Queue()
    13 for i in range(10):
    14   q.put("你好啊")
    15 p = Pool(3)
    16 for i in range(10):
    17   p.apply_async(work1)
    18 p.close()
    19 p.join()

     

  • 相关阅读:
    listctrl中的cell如何支持被复制
    Can not issue data manipulation statements with executeQuery()的解决方案
    Jenkins工具学习(一)
    如何对图片进行测试
    WebDriver常用的api
    Cannot get a STRING value from a NUMERIC cell问题的解决办法
    Eclipse中安装springmvc插件
    Tomcat 的端口被占用的解决办法
    pyCharm最新激活码(2018激活码)
    Error: Error occured while starting App. Original error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity
  • 原文地址:https://www.cnblogs.com/addicated/p/13175336.html
Copyright © 2020-2023  润新知