1.鼠标双击启动图标
2.使用代码创建应用进程
如何用代码创建进程python中有跟进程相关的模块multiprocessing,意思为多进程
from multiprocessing import Process import time def test(name, n): # 用方法建立一个只有进程才能使用的代码 print(f'{name}正在运行') time.sleep(n) print(f'{name}运行结束') if __name__ == '__main__': # __main__方法内的代码只有在程序作为起始文件时触发,避免死循环 p = Process(target=test, args=('jason', 3)) p.start()
使用__main__方法的原因
在python中,创建进程的方式是将文件作为模块再导入一次执行,所以如果把创建进程的文件放在外侧,进程就会无限执行导致死循环,__main__方法内部的代码只有在文件作为起始文件时才触发,作为模块导入则不会触发,这样可以保证不会进入死循环。
使用类与对象批量创建进程class MyProcess(Process): # 继承Process类创建自己的进程类 def __init__(self, name): super().__init__() self.name = name def run(self): # 创建每个进程对象拥有的功能 print(f'{self.name}正在运行') time.sleep(5) print(f'{self.name}运行结束') if __name__ == '__main__': obj = MyProcess('jason') obj.start() print('主进程')join方法
join方法的用途:
中断主程序的代码运行,直到创建的子程序代码运行完毕后才继续运行主程序
from multiprocessing import Process def task(name, n): print(f'{name}正在运行') time.sleep(10) print(f'{name}运行结束') if __name__ == '__main__': p = Process(target=task, args=('jason', 1)) # args就是通过元组的形式给函数传参 p.start() p.join() print('主程序')
此时主程序的打印'主程序',会等到子程序运行完后再运行,无论子程序闲置多久
多进程与joinfrom multiprocessing import Process import time def task(name, n): print(f'{name}正在运行') time.sleep(n) print(f'{name}运行结束') if __name__ == '__main__': p1 = Process(target=task, args=('jason', 1)) # args就是通过元组的形式给函数传参 p2 = Process(target=task, args=('kevin', 2)) p3 = Process(target=task, args=('jerry', 3)) start_time = time.time() p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() end_time = time.time() - start_time print('总耗时:%s' % end_time) print('主进程')
当多进程与join组合时要注意join的位置,join位置不同会影响程序运行的总时间
如下组合,总运行时间为p1+p2+p3,因为p1运行时要等p1运行完毕才执行运行p2
p1.start() p1.join() p2.start() p2.join() p3.start() p3.join()
如下组合,总运行时间为三个中最长的一个,因为三个程序会在极短时间内先后运行
p1.start() p2.start() p3.start() p1.join() p2.join() p3.join()
多进程的数据隔离
多个进程数据彼此之间默认是相互隔离的
from multiprocessing import Process money = 100 def task(): global money money = 666 print('子进程打印的money', money) if __name__ == '__main__': p = Process(target=task) p.start() p.join() print('父进程打印的money', money)
打印结果为
父进程打印的money100,子进程打印的money666
父子程序直接如果需要数据通信,则需要使用队列或通道
队列队列用于父程序与子程序储存程序的多个数据
from multiprocessing import Queue # 1.创建队列对象 q = Queue(3) # 括号内指定队列可以容纳的数据个数 默认:2147483647 # 2.往队列添加数据 q.put(111) print(q.full()) # 判断队列是否已经存满 q.put(222) q.put(333)
如果队列内已满,此时再添加数数据会造成阻塞,直到队列取出数据之后才会继续运行
队列的常见关键字1.Queue()
定义队列,括号数值为最大值,默认最大的储存值为2147483647
2.put()
往队列中输入数值
3.full()
判断队列是否已满,不满输出False,满则输出True
4.get_nowait()
取出目标数据,如果数据不存在会报错
5.empty()
判断队列是否已空,不空输出False,空则输出True
6.get()
取出队列第一个数据,如果队列为空会造成阻塞,直到队列被添加一个数据
注:
q.full()
q.empty()
q.get_nowait()
这三个方法在多进程时会失效,只能在单进程中使用
进程的相关方法1.get_pid()/get_ppid()
查看进程的进程号
计算机会给每个正在运行的进程分配一个进程号,用于方便管理每个进程
2.terminate()
销毁进程
相当于关闭应用程序
3.is_alive()
判断进程是否还在运行,返回值为布尔值
守护进程当一个进程被设置成守护进程时,当被守护的目标进程关闭时,守护进程会一起关闭
p.daemon = True # 必须在start之前执行 p.start()
如果在子进程运行之后才设置守护进程为True,那么会先报错主程序,再执行子程序代码
僵尸进程当一个进程已经运行结束,但是相关的资源并没有完全清空,那么这个进程残留就称为僵尸进程
僵尸进程需要父进程参与回收
父进程意外关闭,子进程正常运行,这个子进程就称为孤儿进程
孤儿进程会被操作系统会自动分配可以接收的进程来接收