进程,Process模块,join方法,ipc机制,守护进程

多道技术:

"""
在学习并发编程的过程中 不做刻意提醒的情况下 默认一台计算机就一个CPU(只有一个干活的人)
"""
单道技术
	所有的程序排队执行 过程中不能重合
多道技术
	利用空闲时间提前准备其他数据 最大化提升CPU利用率
  
多道技术详细
	1.切换
  	计算机的CPU在两种情况下会切换(不让你用 给别人用)
    	1.程序有IO操作
      	输入\输出操作
        	input、time.sleep、read、write
  		2.程序长时间占用CPU	
      	我们得雨露均沾 让多个程序都能被CPU运行一下 

  2.保存状态
  	CPU每次切换走之前都需要保存当前操作的状态 下次切换回来基于上次的进度继续执行
 
"""
开了一家饭店 只有一个服务员 但是同时来了五桌客人
	请问:如何让五桌客人都感觉到服务员在服务他们
		让服务员化身为闪电侠 只要客人有停顿 就立刻切换到其他桌 如此往复
"""

进程与程序的区别:

    程序:一堆死代码(还没有被运行起来)
    进程:正在运行的程序(被运行起来了)


进程的调度算法(重要):


   
1.FCFS(先来先服务)
      对短作业不友好


 
  2.短作业优先调度
      对长作业不友好


    3.时间片轮转法+多级反馈队列(目前还在用)
      将时间均分 然后根据进程时间长短再分多个等级
      等级越靠下表示耗时越长 每次分到的时间越多 但是优先级越低


进程的并行与并发:

并行:-->  多个进程同时执行   必须有多个cpu参与,单个cpu无法实现并行

并发:-->  多个进程看上去像同时执行   单个cpu可以实现,多个cpu肯定也可以

)并行可以称作并发,但是并发不能称作并行


进程三状态:

非阻塞态:

就绪态:所有的进程在被CPU执行之前都必须先进入就绪态等待
运行态:CPU正在执行

阻塞态:

阻塞态:进程运行过程中出现了IO操作 阻塞态无法直接进入运行态 需要先进入就绪态

Process:

异步:不等任务执行完,直接执行下一个任务。(同步:一定要等任务执行完了,得到结果,才执行下一个任务。)

因为运行函数需要时间,所以先执行子进程下面的任务

同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)

第一种方法:

from multiprocessing import Process
import time


money = 1000
def task(name,age):
   print('hello  world',name)
   global money
   money = 666
   time.sleep(3)
   print('go  die',age)

if __name__ == '__main__':
   p1 = Process(target = task,args=('egon',123))  #args后面是元组
   p1.start() #创建子进程  会新生成一个内存空间
   print(money)  #主进程代码打印money   1000
#打印
#1000
#hello  world egon
#go  die 123

第二种方法:

from multiprocessing import Process
import time

class A(Process):
   def __init__(self,name,age):
      super().__init__()  #继承父类的属性
      self.name = name
      self.age = age

   def run(self):
      print('hello  world',self.name,self.age)
      time.sleep(3)
      print('go  die',self.age,self.name)

if __name__ == '__main__':
   obj = A('json',123)  #创建一个obj对象
   obj.start() #创建子进程
   print('stop')
#打印
#stop
#hello  world json 123
#go  die 123 json

进程的join方法:

from multiprocessing import Process
import time


def task(name, n):
    print('%s is running' % name)
    time.sleep(n)
    print('%s is over' % name)


if __name__ == '__main__':
    p1 = Process(target=task, args=('jason1', 1))
    p2 = Process(target=task, args=('jason2', 2))
    p3 = Process(target=task, args=('jason3', 3))
    # p.start()  # 异步
    '''主进程代码等待子进程代码运行结束再执行'''
    start_time = time.time()
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    print(time.time() - start_time)  # 6秒多
    
    
    
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()  #3个子线程同时运行
    p3.join()
    print(time.time() - start_time)  # 3秒多

 IPC机制:

IPC:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取

from multiprocessing import Queue


q = Queue(3)  # 括号内可以指定存储数据的个数
# 往消息队列中存放数据
q.put(111)
# print(q.full())  # 判断队列是否已满
q.put(222)
q.put(333)
# print(q.full())  # 判断队列是否已满
# 从消息队列中取出数据
print(q.get())
print(q.get())
# print(q.empty())  # 判断队列是否为空
print(q.get())
# print(q.empty())  # 判断队列是否为空
# print(q.get())
print(q.get_nowait())

"""
full() empty() 在多进程中都不能使用!!!
"""
from multiprocessing import Queue
def product(q):
    q.put('子进程p添加的数据')

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


if __name__ == '__main__':
    q = Queue()
    # 主进程往队列中添加数据
    # q.put('我是主进程添加的数据')
    p1 = Process(target=consumer, args=(q,))
    p2 = Process(target=product, args=(q,))
    p1.start()
    p2.start()
    print('主')
#打印:   
#主
#子进程获取队列中的数据 子进程p添加的数据

生产者消费者模型:

"""回想爬虫"""
生产者
	负责产生数据的'人'
消费者
	负责处理数据的'人'
    
该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以)

进程对象的多种方法:

1.如何查看进程号
	from multiprocessing import Process, current_process
 	current_process()
 	current_process().pid  
	import os
 	os.getpid()
  	os.getppid()
2.终止进程
	p1.terminate()
	ps:计算机操作系统都有对应的命令可以直接杀死进程
3.判断进程是否存活
	p1.is_alive()
4.start()
5.join()

守护进程:

守护进程会随着守护的进程结束而立刻结束
    eg: 吴勇是张红的守护进程 一旦张红嗝屁了 吴勇立刻嗝屁

from multiprocessing import Process
import time

def task(name):
    print('德邦总管:%s' % name)
    time.sleep(3)
    print('德邦总管:%s' % name)

if __name__ == '__main__':
    p1 = Process(target=task, args=('大张红',))
    p1.daemon = True
    p1.start()
    time.sleep(1)
    print('恕瑞玛皇帝:小吴勇嗝屁了')

僵尸进程与孤儿进程:

'''
僵尸进程
	进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
 	比如进程号、进程执行时间、进程消耗功率等给父进程查看
 	ps:所有的进程都会变成僵尸进程
孤儿进程
	子进程正常运行 父进程意外死亡 操作系统针对孤儿进程会派遣福利院管理

'''

多进程数据错乱问题:

"""
多进程操作数据很可能会造成数据错乱>>>:互斥锁
	互斥锁
		将并发变成串行 牺牲了效率但是保障了数据的安全
"""

 

posted @ 2023-03-29 09:29  无敌大帅逼  阅读(67)  评论(0)    收藏  举报