day 32 multiprocessing模块中Process方法,僵尸进程,孤儿进程,守护进程

multiprocess模块

仔细说来,multiprocess不是一个模块而是python中一个操作、管理进程的包。 之所以叫multi是取自multiple的多功能的意思,在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆,我将这部分大致分为四个部分:创建进程部分,进程同步部分,进程池部分,进程之间数据共享。

 

 

进程的pid 父进程的ppid

import time
import os
a = 1
b = 2
print('子进程:',os.getpid())   #python解释器
print('父进程:',os.getppid())  #pycharm软件
time.sleep(20)
print(a + b)

 

 创建进程的两种方式

#方法一
#大多数都使用方法一创建一个子进程
from multiprocessing import Process

def task(n):    #task 固定写法
    print("开始创建进程.............",n)

#windows环境下想开启子进程一定要 __name__ == '__main__'
if __name__ == '__main__':
    p = Process(target=task,args=(1,),kwargs={"n":1})   #task 固定写法,创建对象时"task"不能加"()",args表示位置参数的,kwargs表示关键字参数
    p.start() #起动一个子进程



#方法2 class MyProcess(Process): #类的写法主要是直接继承"Process" 这个类. def __init__(self,n): super().__init__() #必须先要执行父类的 __init__属性,也就是"Process",要不然会报错 self.n = n def run(self): #子进程的代码全部都要写在这里面 a = 1 b = 2 print("%s is runing" % self.n) if __name__ == '__main__': p = MyProcess("alex") p.start() print("我是主")

 

 验证进程间的内存隔离

from multiprocessing import Process
import  time

x = 1000

def task():
    time.sleep(2)
    global x
    x = 2
    print("子进程:",x)

if __name__ == '__main__':
    p = Process(target=task,)
    p.start()
    time.sleep(5)
    print("主:",x)

 

 

主进程在子程序运行完之后运行

from multiprocessing import Process
def task(n):
    print("我是子进程开始运行了.......",n)
    time.sleep(5)
    print("子进程运行结束")

if __name__ == '__main__':
    p = Process(target=task,args=(1,),name="子进程")   #默认参数不变写法 args=(1,) 后面必须有逗号 name定义子进程的名字
    p.start()
    p.join()   #join 上面的子进程运行完毕之后运行主进程
    print("我是主进程")

 

 

 在一个主进程开启多个子进程

def task(n):
    print('%s is begin' % n)
    time.sleep(3)
    print('%s is over' % n)

def main():
    print('主进程执行.....')

if __name__ == '__main__':
    p1 = Process(target=task,args=('p1',))
    p2 = Process(target=task,args=('p2',))
    p3 = Process(target=task,args=('p3',))

    p1.start()  # 发送一个请求
    p2.start()  # 发送一个请求
    p3.start()  # 发送一个请求
    main()

 

 for循环创建子进程

from multiprocessing import Process
import time

def task(n):
    print("%s 开始运行" % n)
    time.sleep(3)
    print("%s 运行结束了" % n)

if __name__ == '__main__':
    for i in range(1,4):
        p = Process(target=task,args=("p%s" % i,))
        p.start()

 

子进程和主进程的运行顺序"串行"和"并发"

 

串行消耗时间长,并发消耗时间短

##串行##
from multiprocessing import Process
import time

def task(n):
    print('%s is begin' % n)
    time.sleep(3)
    print('%s is over' % n)

def main():
    print('主进程执行.....')

if __name__ == '__main__':
    # 创建三个进程对象

    p1 = Process(target=task, args=('p1',))
    p2 = Process(target=task, args=('p2',))
    p3 = Process(target=task, args=('p3',))
    start_time = time.time()
    # 发起三个请求
    p1.start()
    p1.join()   # 高速我的主进程,你要在我执行完毕之后在运行
    # print(111)
    p2.start()
    p2.join()
    p3.start()
    p3.join()
#     # 如果你要按照上面的写法:串行.
    print(time.time() - start_time)
    main()



##并发##
from multiprocessing import Process
import time

def task(n):
    print('%s is begin' % n)
    time.sleep(n)
    print('%s is over' % n)

def main():
    print('主进程执行.....')

if __name__ == '__main__':
    # 创建三个进程对象

    p1 = Process(target=task, args=(1,))
    p2 = Process(target=task, args=(2,))
    p3 = Process(target=task, args=(3,))
    start_time = time.time()
    # 发起三个请求

    p1.start()
    p2.start()
    p3.start()

    p1.join()  # 1
    p2.join()  # 2
    p3.join()  # 3
    print(time.time() - start_time)
    main()

 

 for循环实现主程序等待等待所有子程序结束之后再运行

from multiprocessing import Process
import time

def task(n):
    print("%s开始运行" % n)
    # time.sleep(3)
    print("%s运行结束" % n)

if __name__ == '__main__':
    lst = []
    for i in range(1,4):
        p = Process(target=task,args=("p%s" % i,))
        p.start()
        p.join() #这里使用join是为了让数字顺序拼接上"1,2,3","p1开始运行,p2开始运行,p3开始运行"
        lst.append(p)   #  把子进程添加到列表内不让在外部执行,如果不添加到列表内在外执行之后就变成了串行.

        for c in lst:  # 拿到列表内的子进程
            c.join()   #通过join执行下面的主程序
    print("我是主程序")

总结:
    1,多个进程使用join,他们之间互不影响.
     p.join() 会将除join方法以外的方法视为主进程的方法(视为串行). 比如:p.start

 

 

 进程和对象的其他参数

from multiprocessing import Process
import time
import os
def task(n):
    print('%s is begin' % n)
    # print(os.getpid())
    print('子进程:', os.getpid(), '主:', os.getppid())
    time.sleep(3)
    print('%s is over' % n)

def main():
    print('主进程执行.....')

# if __name__ == '__main__':
    # p1 = Process(target=task, args=('p1',),name='紫禁城') # 自定制别名
    # p2 = Process(target=task, args=('p2',))
    # p1.start()
    # p2.start()
    # print(p1.name)  # 为进程起别名
    # print(p2.name)
    # p1.start()  # 给操作系统发送请求
    # p1.terminate() # 杀死进程
    # # time.sleep(3)
    # # p1.join()
    # time.sleep(1)
    # print(p1.is_alive())  # 判断进程死活
    # 判断id

    # p1 = Process(target=task,args=(1,))
    # p1.start()
    # # print('子进程:',p1.pid)  # 获取p1进程pid
    # print('子进程:',p1.pid,'主:',os.getpid())

 

 

 僵尸进程和孤儿进程

僵尸进程一般针对linux系统,当一个主进程中的子进程在运行完毕之后,就会产生僵尸进程,但是liux底层有垃圾回收机制(waitpid,内核层面),会默认将僵尸进程回收,如果主进程产生了大量的子进程回收不及时可能会影响的系统性能.

僵尸进程:占有一点空间,保存pid,运行时间,状态,僵尸进程的回收是由主进程发起的.

孤儿进程:当你的主进程意外挂了,就会形成孤儿进程,孤儿进程就会交给linux系统来处理.

 

 守护进程

守护进程会等待主进程的代码结束之后就立即结束

守护进程也是一个子进程,主进程永远要在子进程结束之后才能使用,因为主进程要负责回收子进程

from multiprocessing import Process
import time

def task(n):
    print('%s is begin' % n)
    time.sleep(3)
    print('%s is over' % n)

def main():
    print('主进程执行.....')

if __name__ == '__main__':
    # 创建三个进程对象

    p1 = Process(target=task, args=('p1',))
    p1.daemon = True # 你的p1进程就设置成了守护进程,便不会再执行p1的内容了.
    p1.start()
    time.sleep(2)
    main()

 

转载于:https://www.cnblogs.com/yanpeizhang/p/10439813.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值