进程★★★★★

本文介绍了进程的三种状态:就绪、运行和阻塞,并阐述了进程的基本语法,包括创建进程、异步并发以及子父进程的关系。详细讲解了join的用法,以及如何通过自定义类创建进程。最后,讨论了守护进程的使用,特别是在监控报活中的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

###并行和并发

并发:一个cpu同一时间不停执行多个程序
并行:多个cpu同一时间不停执行多个程序

cpu的进程调度方法
先来先服务fcfs(first come first server):先来的先执行
短作业优先算法:分配的cpu多,先把短的算完
时间片轮转算法:每一个任务就执行一个时间片(时间段)的时间.然后就执行其他的.
多级反馈队列算法
越是时间长的(例如下载),cpu分配的资源越少,优先级靠后
越是时间短的,cpu分配的资源越多

在这里插入图片描述

###同步 异步

场景在多任务当中
同步:必须等我这件事干完了,你在干,只有一条主线,就是同步
异步(由进程触发):没等我这件事情干完,你就在干了,有两条主线,就是异步

###进程(Process)

进程就是正在运行的程序,它是操作系统中,资源分配的最小单位.
一个程序等于一个进程
进程(程序)是由CPU执行
进程是典型的异步过程,可以让CPU执行多个程序
资源分配:分配的是cpu和内存等物理资源
进程号(类似于身份证号码)是进程的唯一标识
同一个程序执行两次之后是两个进程

在这里插入图片描述
例如:
在这里插入图片描述
#CPU执行的时候只执行就绪状态
(1)就绪(Ready)状态
只剩下CPU需要执行外,其他所有资源都已分配完毕 称为就绪状态。
(2)执行(Running)状态
cpu开始执行该进程时称为执行状态。
(3)阻塞(Blocked)状态
由于等待某个事件发生而无法执行时,便是阻塞状态,cpu执行其他进程.例如,等待I/O完成input,sleep,三次握手(监听)申请缓冲区不能满足等等。

进程使用的基本语法

#from multiprocessing import Process(使用进程必须引入)
#查看进程号必须要引入os模块
#如果父进程是一个程序,子进程就是这个程序中的一部分程序
import os
	当前进程id(子进程的进程号)
	res = os.getpid()  
	print(res)
	当前进程的父进程id(父进程的进程号)
	res2 = os.getppid()
	print(res2)

创建进程

process(属于进程类) 永远只创建子进程,返回进程的对象p,
target指定要执行的任务
args指定传递的参数,args的类型是元组,多个参数之间用逗号隔开
创建一个子进程的时候,创建的子进程会有短暂的阻塞,CPU会向下执行,创建的子进程会比主文件执行的要慢一点,呈现出异步现象.
创建的子进程与原进程的数据是隔离
创建子进程一分配空间会有阻塞(只是比较短暂)



创建无参数进程(基于当前文件(父进程),子进程在创建一个子进程,相当于创建的子进程在新的文件中开辟执行,属于不同的程序,并且彼此的数据是独立的,不互通)
def func():
    print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid()))
#windows里面下面这句话必须要加;
if __name__ == "__main__":  ===>if下面打印的是主文件中的子父进程
    print("3.子进程id>>>>{} , 4.父进程id>>>>	{}".format(os.getpid(),os.getppid())) 
    # 子进程在创建(定义)子进程(异步),返回一个进程对象,执行func任务
   	p = Process(target = func) # target指定任务
   	# 调用子进程
   	p.start()


创建带有参数的进程(程序) (基于当前文件(父进程),子进程在创建一个子进程,相当于创建的子进程在新的文件中开辟执行,属于不同的程序,并且彼此的数据是独立的,不互通)
def func(n):
    for i in range(1,n+1):
         print("3.子进程id>>>>{} , 4.父进程id>>>>	{}".format(os.getpid(),os.getppid()))

if __name__ == "__main__":
    print("1.子进程id>>>>{} , 2.父进程id>>>>	{}".format(os.getpid(),os.getppid()))

    n = 5
    # 创建子进程,target指定任务(函数)如果有参数,要通过args给出参数(元组),参数为1个,args就给出一个,如果是两个,args就给出两个,中间用逗号隔开
  	p = Process(target=func,args=(n,))
    # 调用子进程
    p.start()

    for i in range(1,n+1):
       print("*" * i)

多个进程可以异步并发(一个cpu执行多个进程(程序)),子父进程之间的关系

默认一个CPU执行多个进程时,父进程要等到所有子进程结束后在关闭程序(父进程没有了,子进程也不能存在),因为cpu调度策略问题,不一定先执行谁或者后执行谁,整体而言,主进程速度快于子进程,cpu遇到阻塞立刻切换其他任务,等到进程的就绪态在切换回来,主程序会默认等待所有的子进程执行结束之后,在关闭程序,释放资源,若不等待,子进程并不方便管理,容易造成僵尸进程,在后台不停的占用系统的资源(cpu和内存),不清楚进程的来源.

def func(args):
  print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid()) , args)

if __name__ == "__main__":
    for i in range(1,11):  ===>创建10个进程,每个创建的子进程的参数不一样
     Process(target=func,args = (i,)).start()
     print("主进程执行结束 ....  ")

###join

#如何判断所有的子进程都结束,主进程才能执行并且关闭程序用join
功能:等待所有子进程全部执行完毕之后,主进程任务在继续执行,(用来同步子父进程速度的)
multi 代表多 , Process 属于一个类

join 的基于语法

(1)单个子进程配合join使用
def func():
   print("发送第一封邮件")

if __name__ == "__main__":
  	p = Process(target=func)
  	p.start()

    # 必须等待子进程执行结束之后,在继续执行主程序中的代码,用来同步代码一致性的;
    p.join() 
    print("发送第二封邮件")


(2) 多个子进程配合join使用
def func(index):
print("发送第%s封邮件" % (index))

if __name__ == "__main__":
  lst = []
  for i in range(10):  ====>创建10个不同的异步进程
 	   p = Process(target=func,args=(i,))
 	   p.start()  ====>所有异步进程同时进行(速度快)
 	   lst.append(p)
 	   # p.join()# 程序会变成同步阻塞,减慢的速度
    
   for i in lst:  ====>等到所有异步执行完以后,在去同步阻塞(不要先去阻塞)
       print(i)
        i.join()

   print("主进程发最后一封邮件,里面的内容是我发完了")

###使用自定义类的方式创建进程(拓展,了解)

自定义类创建进程要求:
(1) 必须继承Process这个父类
(2) 所有进程执行任务的逻辑要写run方法里面

基本语法

class MyProcess(Process):
	def run(self):
   	  print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid()))
   	  if __name__ == "__main__":
 	p = MyProcess()
   	p.start()
    print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid()))

有参数的进程函数

class MyProcess(Process):

  def __init__(self,arg):
     # 手动调用一下父类的构造方法(实现进程的创建)
	    super().__init__()
	    self.arg = arg


def run(self):
    print("1.子进程id>>>>{} , 2.父进程id>>>>{}".format(os.getpid(),os.getppid()),self.arg)

if __name__ == "__main__":
p = MyProcess("我是参数")
p.start()
print("3.子进程id>>>>{} , 4.父进程id>>>>{}".format(os.getpid(),os.getppid()))

###守护进程

守护进程守护的是主进程,如果主进程执行结束了,意味着守护进程的寿命立刻终止.立刻杀死
语法:
进程.daemon = True 设置当前进程为守护进程
必须写在start()调用进程之前进行设置

默认情况下,主进程会等待所有子进程执行完毕之后,关闭程序,释放资源
守护进程在主进程代码执行结束之后,直接杀掉.非守护进程,主进程还是会默认等待的.

基本用法

def func():
    print("start 当前子进程")
   print("end   当前子进程")

if __name__ == "__main__":
   p = Process(target=func)
   p.daemon = True
   p.start()
   print("主进程执行结束 ... ")

多个子进程的场景

import time
def func1():
    count = 1
    while True:
      print("*" * count)
      time.sleep(0.5)
      count += 1

def func2():
    print("start func2当前子进程")
    time.sleep(2)
    print("end   func2当前子进程")


if __name__ == "__main__":
    p1 = Process(target=func1)
    p2 = Process(target=func2)

   # 设置当前进程为守护进程
    p1.daemon = True

    p1.start()
    p2.start()

    time.sleep(1)

   # 非守护进程,主进程还是会默认等待的.
   print("主程序代码结束....")

守护进程的实际用途: 监控报活

在这里插入图片描述

import time
监控报活 ===>随时记录5号功能报告给监控服务器
def alive():
    while True:
      print("给监控服务器发消息, 当前5号服务器功能正常 i am ok ~")
      time.sleep(1)
      
当前服务器正常完成的功能(记录报表)
def func():
    # while True:
    time.sleep(5)
    print("当前5号服务器功能,统计财务报表~")


if __name__ == "__main__":
    p1 = Process(target=func) ====>如果有一天这个服务器炸了,停止运行,就会走主文件的代码
    p2 = Process(target=alive) ==>监控报活必须跟着服务器走
    p2.daemon = True

    p1.start()
    p2.start()

    # 等待p1子进程执行结束之后,下面的主程序的代码才会放行;
    p1.join()

    print("当前服务器状态:统计财务报表功能异常.....")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值