栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Python

Python进程详解

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python进程详解

文章目录
  • 一、 创建进程的多种方法
  • 二、 Join方法
  • 三、 进程间数据默认隔离
  • 四、 进程间通行(IPC机制)
  • 五、 生产者消费者模型
  • 六、 进程相关方法
  • 七、 守护进程
  • 八、 僵尸进程与孤儿进程

一、 创建进程的多种方法
	首先回想上片我们讲到进程 进程就是运行中的代码 那我们怎么创建呢?
	创建进程的两种方法:
			1. 双击桌面图标程序(打开程序 底部代码运行就是创建进程)
			2. 代码创建进程(两种方法)		需要用到模块mutiprocessing、Process
			
			首先说明:
				在创建进程的代码在不同的的操作系统中底层原理是不一样的有区别的!
				在WiINDOWS里 创建进程类似于导入模块
					需要用到 if __name__ == '__main__': 启动脚本 (要不然报错)
				在MAC LINUX中 创建进程类似于直接拷贝
					不需要启动脚本 但是为了更好的兼容性 加上启动脚本更好
	方法1: 创建函数
			from multiprocessing import Process			# 导入模块
			import time

			def task(name):								# 设置函数
			    print(f'{name}正在运行')
			    time.sleep(3)
			    print(f'{name}运行结束')
			
			if __name__ == '__main__':					# 运行脚本 
			    p = Process(target=task, args=('LebronJames',))  # 创建一个进程对象
			    p.start()  # 告诉操作系统创建一个进程(异步操作)
			    # task('LebronJames')  # 普通的函数调用是同步操作
			    print('主进程')
			
			result: 主进程 LebronJames正在运行 LebronJames运行结束

	方法2: 创建类
			from multiprocessing import Process			# 导入模块
			import time
			
			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('LebronJames')
			    obj.start()
			    print('主进程')
			
			result: 主进程 LebronJames正在运行 LebronJames运行结束

		'''底层原理都是 先运行完父类的代码 创建一个进程空间运行子类的代码'''
二、 Join方法
			'''join:主进程等待子进程运行结束之后再运行'''
		
			from 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=('LebronJames', 1))  # args就是通过元组的形式给函数传参
			    p2 = Process(target=task, args=('DwightHoward', 2)) # 也可以通过kwargs={'name':'jason', 'n':1}
			    p3 = Process(target=task, args=('Like', 3))
			    start_time = time.time()                            # 开始计算时间
			    p1.start()
			    p2.start()
			    p3.start()
			    p1.join()                                           # 注意 join放在哪里结果时间都有变化
			    p2.join()                                           # 如果放在所有创建进程下又不一样
			    p3.join()						
			
			    end_time = time.time() - start_time                 # 结束时间
			    print('总耗时:%s' % end_time)
			    print('主进程')

				result: LebronJames正在运行 DwightHoward正在运行 Like正在运行 LebronJames运行结束
						DwightHoward运行结束 Like运行结束 总耗时:3.1185059547424316 主进程

三、 进程间数据默认隔离
	多个进程数据彼此之间默认是相互隔离的(每个有各自的进程空间互不干扰)
	如果真的想要交互 需要借助 管道与队列
			from multiprocessing import Process
			money = 100		 # 父进程的全局money
			
			def task():
			    global money
			    money = 666			# 子进程的局部money
			    print('子进程打印的money', money)
			
			if __name__ == '__main__':
			    p = Process(target=task)
			    p.start()
			    p.join()					    #  join等待子进程结束再运行父进程
			    print('父进程打印的money', money)
			 
			 result: 子进程打印的money 666 父进程打印的money 100
	'''总结到底还是 子是子 父是父 互不干扰'''

四、 进程间通行(IPC机制)
	from multiprocessing import Queue
	q = Queue(1)           # 创建队列对象 括号内指定队列可以容纳的数据个数 默认:2147483647
	q.put(111)             	# 2.往队列添加数据
	print(q.full())        		# 判断队列是否已经存满
	q.put(222)             	# 超出数据存放极限 那么程序一致处于阻塞态 直到队列中有数据被取出
	print(q.get_nowait())  # 3.从队列中取数据
	print(q.get_nowait())  # 队列中如果没有数据可取 直接报错
	print(q.get())         	# 获取数据
	print(q.empty())      	# 判断队列是否已经空了
	print(q.get())         	# 超出数据获取极限 那么程序一致处于阻塞态 直到队列中有数据被添加

	'''上述方法在多进程下不能准确的使用(或者失效)'''
	IPC机制
		1.主进程与子进程通信
	 	2.子进程与子进程通信
		
		from multiprocessing import Queue, Process
		from multiprocessing import set_start_method	# Mac是通过os.fork()开启的子进程
		set_start_method('fork')			# 默认多进程开启方式是spawn
		
		def procedure(q):
		    q.put('子进程procedure往队里中添加了数据')
		
		def consumer(q):
		    print('子进程的consumer从队列中获取数据', q.get())
		
		
		if __name__ == '__main__':
		    q = Queue()  # 在主进程中产生q对象 确保所有的子进程使用的是相同的q
		    p1 = Process(target=procedure, args=(q,))
		    p2 = Process(target=consumer, args=(q,))
		    p1.start()
		    p2.start()
		    print('主进程')
		result: 主进程 子进程的consumer从队列中获取数据 子进程procedure往队里中添加了数据
五、 生产者消费者模型
	生产者 产生数据
	消费者 处理数据
		例如爬虫 生产者:获取网页数据的代码(函数)爬
						消费者:从网页数据中筛选出符合条件的数据(函数)筛选
	完整的生产者消费者模型至少有三个部分
		生产者 消息队列/数据库 消费者
六、 进程相关方法
	查看进程号(每一个端口号进程号都是不一样的)
	两种方法
		from multiprocessing import current_process
			current_process().pid			# 获取进程号
		import os
			os.getpid()						# 获取进程号
			os.getppid()					# 获取父的进程号
		p1.terminate()						# 销毁子进程
		p1.is_alive()						# 判断进程是否存活
		from multiprocessing import Process
		from multiprocessing import current_process
		money = 100
		def task():
		    global money
		    money = 666
		    print('子进程打印的money', money)
		    print('子进程的PID', current_process().pid)
		    
		if __name__ == '__main__':
		    p = Process(target=task)
		    p.start()
		    p.join()
		    print('父进程打印的money', money)
		    print('父进程的PID', current_process().pid)
七、 守护进程
	什么是守护
		伴随着守护对象的存活而存活 死亡而死亡
		需要用到daemon方法
		from multiprocessing import Process
		import time

		def task(name):
		    print('大内总管:%s存活' % name)
		    time.sleep(3)
		    print('大内总管:%s嗝屁' % name)
	
		if __name__ == '__main__':
		    p = Process(target=task, args=('基佬',))
		    p.daemon = True  # 将子进程设置为守护进程:主进程代码结束 子进程立刻结束
		    p.start()
		    # p.daemon = True  # 必须在start之前执行 如果在start下面运行就报错
		    print('天子LebronJames寿终正寝!!!')

		result: 天子LebronJames寿终正寝!!!
八、 僵尸进程与孤儿进程
	僵尸进程
		进程已经运行结束 但是相关的资源并没有完全清空(子进程还在运行)
		需要父进程参与回收
	孤儿进程
		父进程意外死亡 子进程正常运行 该子进程就称之为孤儿进程(单进程结束就结束了)
		孤儿进程也不是没有人管 操作系统会自动分配福利院接收
转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037078.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号