进程

进程号是进程的唯一标识

查看方式:

1.在终端查看  tasklist

2.在本文件查看

  查看子进程 : os.getpid()

  查看父进程 : os.geippid()

tasklist| findstr python    在终端输入,只查看python解释器中的进程

创建进程的两种方式

1.常用

from multiprocessing import Process
a = 1
b = 2

def task(n):
    print('%s is running'%n)

#windows环境下想开启子进程一定要在 __name__ == '__main__'下
if __name__ == '__main__':
    # p = Process(target=task,args=(1,))           #p就是一个进程对象   通过args传参,必须是元祖形式
    p = Process(target=task,kwargs={'n':1})        #也可以通过kwargs传参,字典形式
    p.start()    #给操作系统发送一个请求
    print('主进程')

 

2.利用创建好的框架去构建进程  好处是很多方法和功能都提供好了,方便快捷,弊端是只能按照规定去写

from multiprocessing import Process
class MyProcess(Process):
    def __init__(self,n):
        super().__init__()
        self.n = n
    def run(self):
        a = 1
        b = 2
        print('%s is running' % self.n)

if __name__ == '__main__':
    p = MyProcess('alex')
    p.start()
    print('主进程')

 

验证进程间的内存隔离

from multiprocessing import Process
import time

x = 1000

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

if __name__ == '__main__':
    p = Process(target=task,)
    p.start()
    time.sleep(5)           #先打印子进程,在打印主进程,看结果x是否被子进程修改
    print('主进程:',x)

    
结果:
子进程: 2
主进程: 1000

 

主进程在子进程结束后再运行    join方法

from multiprocessing import Process
import time

x = 1000

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

def main():
    print('主程序执行')

if __name__ == '__main__':
    p = Process(target=task,args=(1,))
    p.start()
    p.join()     #通知p,子进程结束后,再执行主程序
    main()

 如果创建多个进程对象,发起请求之后,运行的顺序不固定

for循环实现:

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__':
    for i in range(1,11):
        p = Process(target=task,args=('p%s'%i,))
        p.start()
    '''
    十个子进程请求几乎是同同时发起,谁先到达操作系统,操作系统给谁开辟空间,让cpu执行.
    '''
    main()

 

for循环开启三个进程兑现,然后循环join三个子进程

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__':
    p_ls = []
    start_time = time.time()
    for i in range(1,4):
        p = Process(target=task,args=('p%s'%i,))
        p.start()
        p.join()
        p_ls.append(p)

    for p in p_ls:
        p.join()
    print(time.time() - start_time)
    main()    

多个进程使用join,他们之间互不影响.

p.join() 会将除join方法以外的方法视为主进程的方法. 比如:p.start

进程对象的其他参数

name        为进程起一个别名

terminate   终止进程

is_alive      判断进程是否还存在

from multiprocessing import Process
import time
import os

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

def main():
    print('主程序执行')

if __name__ == '__main__':
    p = Process(target=task,args=(1,),name='子进程')
    p.start()
    print(p.name)       #为进程起别名
    p.terminate()       #杀死进程
    time.sleep(2)
    p.join()            #因为杀死进程和判断进程死活几乎是同时进行,判断可能在杀死进程之前执行,为确保杀死进程,睡一会或者使用join
    print(p.is_alive())   #判断进程死活   返回布尔值

 

在主进程和子进程中分别查看pid值

from multiprocessing import Process
import time
import os

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

def main():
    print('主程序执行')

if __name__ == '__main__':
    p = Process(target=task,args=(1,),name='子进程')
    p.start()
    print('子进程:', p.pid, '主进程:', os.getpid())   # 进程对象.pid也可以得到当前的pid值

 

僵尸进程与孤儿进程

(在linux系统才会出现)

理论上,各个进程的开启和结束互相不影响,不依赖

进程空间在内存中真正的消失才算是进程结束,主进程都是等着子进程结束之后才关闭

子进程是在主进程的基础上创建的,并且结束子进程的时间节点,主进程必须要知道

 

僵尸进程:死而不腐  主进程或者存在多个子进程时,代码结束时没有完全死掉,它们形成了僵尸进程,只会保存pid,退出状态和运行时间

主进程要获取僵尸进程保留的数据:

1.僵尸进程会占用一点空间,占用pid进程号,再想开启新进程的时候,可能会会出现因为没有进程号导致的开启不了

2.僵尸进程的回收是由主进程发起的

孤儿进程:主进程意外终止,剩下多个子进程就形成孤儿进程

在linux系统中,只要启动了子进程,内存中就会建立一个init主进程,是所有进程的主进程,最后的回收由init来执行

僵尸进程有害.僵尸进程的回收取决于主进程,如果主进程产生了大量的子进程,但是不着急回收这些僵尸进程,占用内存和pid号

孤儿进程无害.都会被init主进程回收

具体回收方法: waitpid()

守护进程

子进程守护主进程

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

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.start()
    time.sleep(2)         # 子程序中的睡眠时间为3秒,当这时的两秒睡完之后,子程序不再执行,直接向下执行,调用main()函数
    main()

 

posted @ 2019-02-27 19:06  Sandy-123  阅读(119)  评论(0编辑  收藏  举报