• python并发编程之多进程


    一,multiprocessing模块结束

    python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。
        multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。

      multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

        需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。

    二,Process类的介绍

    p=Process(target=task,args=('子进程',))

    #由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

    强调:

    1,args指定的为传给target函数的位置参数,是一个元祖形式,如果只有一个参数的话,一定记住加逗号。

    2.target表示调用对象,即子进程要执行的任务。

    3.args表示调用对象的位置参数元祖。

    4 .   p.start()  只是在向操作系统发送一个开启子进程的信号。

    三,创建并开启子进程的两种方式:

    方式一:(用默认类的方式)

    # from multiprocessing import Process
    # import time
    #
    # def task(x):
    # print('%s is running' %x)
    # time.sleep(3)
    # print('%s is done' %x)
    #
    # if __name__ == '__main__':
    # # Process(target=task,kwargs={'x':'子进程'})
    # p=Process(target=task,args=('子进程',)) # 如果args=(),括号内只有一个参数,一定记住加逗号
    # p.start() # 只是在操作系统发送一个开启子进程的信号
    #
    # print('主')


    方式二:(自定义类的方式)

    # from multiprocessing import Process
    # import time
    #
    # class Myprocess(Process): #自定义类
    # def __init__(self,x):
    # super().__init__()
    # self.name=x
    #
    # def run(self): #把子进程想执行的任务放到run下面的函数体代码
    # print('%s is running' %self.name) #self是p
    # time.sleep(3)
    # print('%s is done' %self.name)
    #
    # if __name__ == '__main__':
    # p=Myprocess('子进程1')
    # p.start() #等于是自动调用 p.run()
    # print('主')

    补充:
    僵尸进程和孤儿进程

    一:僵尸进程(有害)
      僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。


    父进程代码运行完毕后,等待子进程代码运行完进入僵尸状态(保留PID,其他都没了,就叫僵尸状态),最后父进程统一发起回收
    子进程僵尸的操作。

    二:孤儿进程(无害)
    
      孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。


    四,进程内存空间彼此隔离

    from multiprocessing import Process
    n=100 #在windows系统中应该把全局变量定义在if __name__ == '__main__'之上就可以了
    def work():
        global n
        n=0
        print('子进程内: ',n)
    
    
    if __name__ == '__main__':
        p=Process(target=work)
        p.start()
        print('主进程内: ',n)


    用以上方法来证明,内存空间是彼此隔离的。

    在子进程中用global声明了全局变量,且把n=100改为0,当主进程进行打印的时候,n=100没变,说明内存空间是隔离的。

    五,进程对象的方法或属性详解。

    join方法

    join方法,是父进程在原地等,等到子进程运行完毕后,才执行下一行代码

    #1、join
    # from multiprocessing import Process
    # import time
    #
    # def task(name):
    # print('%s is running ' %name)
    # time.sleep(3)
    # print('%s is done ' % name)
    #
    #
    # if __name__ == '__main__':
    # p=Process(target=task,args=('子进程1',))
    # p.start()
    # p.join() # 让父进程在原地等待,等到子进程运行完毕后,才执行下一行代码
    # print('主')


    启动进程与join进程可以简写为:

    # from multiprocessing import Process
    # import time
    #
    # def task(name,n):
    # print('%s is running ' %name)
    # time.sleep(n)
    # print('%s is done ' % name)
    #
    #
    # if __name__ == '__main__':

    #
    # p_l=[]
    # start=time.time()
    # for i in range(1,4):
    # p=Process(target=task,args=('子进程%s' %i,i))
    # p_l.append(p)
    # p.start()
    #
    # # print(p_l)
    # for p in p_l:
    # p.join()
    #
    # stop=time.time()
    #
    # print('主',(stop-start))



    PID方法:
    是进程的ID号

    p1子进程是在父进程中造出来的。在父进程中查看子进程的ID,用p1.pid
    如果在子进程中看自己的ID,用 os.getpid()


    一,父进程内查看子PID的方式:

    # pid
    # from multiprocessing import Process
    # import time
    # import os
    #
    # def task(n):
    # print('%s is running ' %os.getpid())
    # time.sleep(n)
    # print('%s is done ' % os.getpid())
    #
    #
    # if __name__ == '__main__':
    # p1=Process(target=task,args=(10,))
    # # print(p1.pid)
    # p1.start()
    # print(p1.pid) # 父进程内查看子pid的方式
    # print('主')



    二,查看父进程自己的PID(用 os.getppid())
    from multiprocessing import Process
    import time
    import os

    def task():
    print('自己的id:%s 父进程的id:%s ' %(os.getpid(),os.getppid()))
    time.sleep(200)

    if __name__ == '__main__':
    p1=Process(target=task)
    p1.start()
    print('主',os.getpid(),os.getppid())
    # 爹=》主--》儿子




  • 相关阅读:
    Spark-sql windows 下 执行错误.
    notepad ++ 注册表
    log4j 配置文件 示例
    linux 查看 进程 内存占用
    spring boot 常见错误解决
    python 轻量 web 框架 Bottle 使用
    Spring cloud eureka 添加 spring-security
    vue can‘ not resolver sass-loader 的 解决办法。
    外国人眼中的珍珠奶茶是啥?
    75.2亿美元:诺基亚、微软终于在一起
  • 原文地址:https://www.cnblogs.com/fxc-520520/p/9295350.html
Copyright © 2020-2023  润新知