• 并发编程之多进程(更新中...)


    并发编程之多进程

    multiprocessing模块介绍

    • 功能
      • 子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

    Process类使用

    Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)  
    强调:
        1. 需要使用关键字的方式来指定参数 
        2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
    
    • 参数

      • 1 group参数未使用,值始终为None
        2 target表示调用对象,即子进程要执行的任务
        3 args表示调用对象的位置参数元组,args=(1,2,'kuck',)
        4 kwargs表示调用对象的字典,kwargs={'name':'kuck','age':18}
        5 name为子进程的名称
        
    • 方法

      • 1 group参数未使用,值始终为None 
        2 target表示调用对象,即子进程要执行的任务
        3 args表示调用对象的位置参数元组,args=(1,2,'kuck',)
        4 kwargs表示调用对象的字典,kwargs={'name':'kuck','age':32}
        5 name为子进程的名称
        
    • 属性

      • 1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置 
        2 p.name:进程的名称
        3 p.pid:进程的pid
        4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
        5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功
        
    • .join方法的使用

      • #作用:父进程等待子进程结束
        from multiprocessing import Process
        def task(i):
            print(i)
        if __name__ == '__main__':
            for i in range(10):
                p = Process(target=task,args=(i,))
                p.start()
                p.join()
            print("主进程结束")
        

    多路复用技术

    • 空间隔离
      • 多个程序共用一个内存条,彼此隔离,物理级别隔离
    • 时间隔离
      • 多个程序共用一个cpu
    • cpu并行情况下切换的条件
      • i/o阻塞
      • 占用时间过长

    串行、并行、并发

    • 串行:完完整整的执行完一个程序再执行下一个程序
    • 并发:单核cpu同时运行多个程序
    • 并行:多个cpu同时运行多个程序

    开启子进程的两种方式

    • 方式1

      • from multiprocessing import Process
        def task():
            pass
        if __name__ == '__main__':
            p = Process(target=task)
            p.start()
        
    • 方式2

      • from multiprocessing import Process
        class myP(Process):
            def run(self):
                pass
        if __name__ == '__main__':
            p = myP()
            p.start()
        

    僵尸进程、孤儿进程、守护进程

    • 僵尸进程

      • 没有死透的子进程(pid并没有被父进程回收)
    • 孤儿进程

      • 父进程结束,子进程还在运行,孤儿进程通常会被init接管,init相当于孤儿院,会等待子进程运行结束后回收
    • 守护进程

      • 在主进程最后一行代码结束之后立即结束

      • p = Process(target=task)
        p.daemon = True
        

    进程锁的概念与用途

    • 把锁住的代码变成串行

    • 与join比较,join将所有的子程序变成串行,而进程锁只是将锁住的代码变成串行

    • 实例代码

      • from multiprocessing import Process,Lock
        import time
        def task():
            print("11")
        def task1():
            print("2222")
        def task3(lock1):
            task()
            lock1.acquire()
            time.sleep(2)
            task1()
            lock1.release()
        if __name__ == '__main__':
            lock1 = Lock()
            for i in range(30):
                p = Process(target=task3,args=(lock1,))
                p.start()
        

    队列(队列(Queue) = 管道(PIPE) + 锁(Lock))

    • 队列赋值

    • q = Queue(队列中的数的最大数量)
      q.put(block=True,timeout=5) 参数block的意义在队列达到最大数量时是否阻塞,默认为阻塞(True)
      timeout的意义是设置最大阻塞时间
      
    • 队列取值

      • q.get(block=True,timeout=5) 这里的block与timeout与上面的一样
        
    • 生产者消费者模型

      • 生产者<---->队列<----->消费者

      • 作用:生产消费者模型大大提高了生产者的生产效率和消费者的消费效率.

      • Joinablequeues使用

        • q.put(相当于在队列中+1) 
          q.get();q.task_dowm()相当于在队列中减一
          
        • 这里面的join的作用是等待计数器为0

    • 代码实现

      • from multiprocessing import JoinableQueue,Process
        import time
        def shengchanzhe(q,name,food):
            for i in range(1,3):
                print(f"{name}生产了{food}{i}")
                res = f"{food}{i}"
                q.put(res)
        
        def xiaofeizhe(q,name):
            while True:
                res = q.get()
                time.sleep(1)
                print(f"{name}吃了{res}")
                q.task_done()
        if __name__ == '__main__':
            q = JoinableQueue()
            p1 = Process(target=shengchanzhe,args=(q,'厨师1','包子'))
            p2 = Process(target=shengchanzhe,args=(q,'厨师2','面条'))
            p3 = Process(target=shengchanzhe,args=(q,'厨师3','米饭'))
            c1 = Process(target=xiaofeizhe,args=(q,'小明'))
            c2 = Process(target=xiaofeizhe,args=(q,'小红'))
            p1.start()
            p2.start()
            p3.start()
            c1.daemon=True
            c2.daemon=True
            c1.start()
            c2.start()
            p1.join()
            p2.join()
            p3.join()
            q.join()
        

  • 相关阅读:
    [Spring Unit Testing] Spring Unit Testing with a Java Context
    [Docker] Benefits of Multi-stage Builds
    [Mockito] Mock List interface
    Android自定义垂直滚动自动选择日期控件
    关于 MVC 字段 默认值
    Qt Creator编译时:cannot open file 'debugQtGuiEx.exe' File not found
    ListView开发笔记
    C/C++误区四:char c = getchar();
    ORACLE 中写入txt文本与从Txt文件中读入数据 修改表结构
    wikioi 1214 线段覆盖
  • 原文地址:https://www.cnblogs.com/kuck/p/11530355.html
Copyright © 2020-2023  润新知