进程知识点补充

本文详细介绍了使用Python的multiprocessing模块创建进程的不同方式,包括基本的Process类和自定义类实例化。讲解了join方法的应用,以及进程间数据的隔离与通信机制,如队列和生产者消费者模型。还探讨了守护进程、僵尸进程与孤儿进程的概念,以及互斥锁在模拟抢票场景中的运用。
摘要由CSDN通过智能技术生成

今日内容概要

  • 创建进程的多种方式
  • join方法
  • 进程间数据默认隔离
  • 进程间通信(IPC机制)
  • 生产者消费者模型
  • 进程相关方法
  • 守护进程
  • 僵尸进城与孤儿进程
  • 互斥锁

创建进程的多种方式

1.创建进程的本质
在内存中申请一块内存空间用于运行相应的程序代码。
2.创建进程的方式
鼠标双击桌面一个应用,启动一个应用,就是会启动和创建一些进程。

3.代码创建进程
在不同的操作系统创建进程的要求不一样:

  • 在windows中创建进程是以导模块的方式进行,所以创建进程的代码必须写在__main__子代码中,否则会直接报错,因为在无限制创建进程(进入死循环)
  • 在linux和mac中创建进程是直接拷贝一份源代码然后执行,不要写在__main__子代码中。
# 第一种创建进程的方式
import time
from multiprocessing import Process

# 创建一个函数
def task(name):
	print('%s is running' % name)
	time.sleep(3)
	print('%s is over' % name)

if __name__ == 'main':
	# 创建一个进程对象
	p = Process(target=task,args=('kk',))
	# 告诉操作系统创建一个进程
	p.start()
	print('主进程')


# 第二种创建进程的方式
from mutiprocessing import Process
import time

# 创建一个类继承Process父类,来使用其中的方法
class Myprocess(Process):
	def __inti__(self,name):
	super().__init__()
	self.name = name

	def run(self):
	print(f'{self.name}正在运行')
	time.sleep(3)
	print(f'{self.name}运行结束')

if __name__ == 'main':
	# 创建一个进程对象
	obj = Myprocess('kk')
	# 告诉操作系统创建了一个进程
	obj.start()
	print('主进程')

join方法

1.概念:
主进程等待子进程结束之后在运行
2.推导

  • 直接在主进程代码中添加time.sleep()让主进程延时,至子进程运行结束;
    不合理,因为无法准确地把握子进程的执行时间,
  • 利用join方法

3.代码实操

import time
from muliprocessing import Process

def task(name,n):
	print(f'{name}正在运行')
	time.sleep(n)
	print(f'{name}运行结束') 

if __name__ == 'main':
	# 创建一个进程对象
	p1 = Process(target = task,args = ('kk',3))
	p2 = Process(target = task,args=('jj',2))
	t1 = time.time()
	# 创建一个进程
	p1.satrt()
	# 这里 通过join方法,将两个子进程一个个运行
	p1.join()
	p2.start()
	# 等子进程运行完,在继续运行主进程
	p2.join()
	end_time = time.time() - t1
	print(f'程序运行时间'{end_time})
	print('主进程')

进程间数据默认隔离

多个进程数据彼此之间默认是相互隔离的

  • 如果想要交互,需要借助于管道队列。
# 父进程与子进程完全是两个空间,可以看成是平行世界,子进程不管怎么改都不影响父进程这边的代码
from multiprocessing import Process
money = 100
def task():
	dlobal money
	money = 666
	print(f'子进程{money}$')


if __name__ == '__main__':
	p1	 = Process(target=task)
	p1.start()
	p1.join()
	print(f'父进程有{money}$')

进程间通信(IPC机制)

1.队列与栈
队列:先进后出(类似于排队)
栈:先进后出(类似于子弹装进弹夹)

2.代码展示

from multiprocessing imort Queue

# 先创建队列列表
q = Queue(3)   # 括号内参数为可容纳的数据个数,默认为2147483647
# 往队列添加数据
q.put(111)

# 判断队列是否已经存满
print(q.full())
q.put(222)
q.put(333)
print(q.full())
# 超出数据存放极限,那么程序一直处于阻塞态,知道队列中有数据被取出
# 1.put(444)

# 从队列中获取数据
print(q.get())  # 如果取不到会进入阻塞态
q.put(444)
print(q.get())
print(q.get_nowait()) #如果 被取完了 会直接报错
# print(q.get_nowait())  #如果队列中 之后没有数据可取 俺么会直接报错
# 判断队列是哦福已经空了
print(q.empty())

q.full() 判断队列内是否存满,可以刚判断完里面的数据就被改动了,下面同理
q.empty()
q.get_nowait()
上述方法在多进程下不能准确使用

3.IPC机制
主进程与子进程通信

from mutiprocessing import Queue,Proces

def procedure(q):
	q.put('子进程procedure往队列中添加的数据')

def consumer(q):
	print('子进程的consumer 从队列中获取数据'q.get())

if __name__ == '__main__':
   # 在主进程中 产生q对象 确保所有的子进程使用的是相同的q
   q = Queue()
   p1 = Process(target=procedure,args=(q,))
   p2 = Process(target=consumer,args=(q,))
   p1.start()
   p2.start()
   print('主进程')
   # print('主进程 从队列中获取数据',q.get())

# 通过将 q对象创建在 主程序中, 那么子程序在产生时都会 经过q对象

生产者消费者模型

1.生产者
产生数据
2.消费者
处理数据
3.完整的生产者消费者模型至少有三个部分
生产者,消息队列,消费者
4.举栗子
爬取红牛分公司地址:

  • 生产者:获取的网页数据的代码(函数)
    消费者:从网页数据中筛选出符合条件的数据(函数)

进程相关方法

1.查看进程号

# 通过 current_process:
from multiprocessing import current_process
print (current_process().pid)    # 查看当前进程号
# 通过os模块
import os
print(os.getpid())    # 查看当前进程号
print(os.getppid())    # 查看它的父进程  进程号  即主进程号     

2.销毁子进程

p1.terminate()

3.判断进程是否存货

# 我们都是跟操作系统打交道,都是异步的,所以代码运行速度很快,操作系统没有反应那么快
p1.is_alive

守护进程

1.如何理解守护进程
伴随着守护对象的存活儿存活,死亡而死亡

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=('kk',))
	# 将子进程设置为守护进程:主进程代码结束,子进程立刻结束
	p.deamon = True
	p.start()
	print('主进程')

僵尸进程与孤儿进程

1.僵尸进程
进程已经运行结束了,但是相关的资源并没有完全清空;
需要父进程参与回收。
2.孤儿进程
父进程意外死亡,子进程正常运行,该子进程就称之为孤儿进程;
孤儿进程也不是没有人管,操作系统会自动分配福利院接收。

互斥锁

模拟抢票
查票;买票

from multiprocessing import Process
import time
import json
import random


# 查票
def search(name):
   with open(r'data.json', 'r', encoding='utf')as data_r:
       data = json.load(data_r)
   print(f'{name}正在查票 当前余票{data.get("ticket_num")}')


# 买票
def buy(name):
   # 再次确认票
   with open(r'data.json', 'r', encoding='utf')as data_r:
       data = json.load(data_r)
   # 模拟网络延迟
   time.sleep(random.randint(1, 3))
   if data.get('ticket_num') > 0:
       data['ticket_num'] -= 1
       with open(r'data.json', 'w', encoding='utf')as data_w:
           json.dump(data, data_w)
       print('%s 买票成功' % name)
   else:
       print('%s 很倒霉 没有轮到票' % name)

def run(name):
   search(name)
   buy(name)

if __name__ == '__main__':
   for i in range(20):
       p = Process(target=run,args=('用户%s'%i,))
       p.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值