进程

打印 上一主题 下一主题

主题 975|帖子 975|积分 2935

1 什么是进程

进程是系统进行资源分配和调度的基本单位,进程表示程序正在执行的过程,是‘活的’,而程序就是一推躺在硬盘上的代码,是‘死的’。
2 进程的调度

1.先来先服务调度算法:对长作业有利,对短作业无利
2.短作业优先调度算法:对短作业有利,对长作业无利
3.时间片轮转法+多级反馈队列
该方法是指,将时间片切成n份,每一份表示一个时间片,这些时间片有一个优先级顺序,最上面的优先执行,一个长任务第一个时间片没有完成会被放到第二个,如果第一个时间片有来任务会优先等第一个执行完在执行第二个。
3 进程的三状态图


4. 如何创建进程

4.1 进程创建的第一种方式(掌握)
  1. from multiprocessing import Process  # 导入进程模块
  2. import time
  3. # 子进程函数
  4. def func(name):
  5.     print('支线%s'% name)
  6.     time.sleep(3)
  7.     print('over%s'% name)
  8. # windows下创建进程,一定要在main下面创建
  9. # 因为windows创建进程类似于模块导入的方式,会从上往下依次执行,如果放在main外面,会一直创建进程下去
  10. # linux系统中只是将代码拷贝一份,因此不需要在main下面创建
  11. # main表示当该文件是执行文件时才会被运行,该文件是导入的形式时不会被运行
  12. if __name__ == '__main__':
  13.     # 1.创建进程对象
  14.     # 参数1:需要创建进程的目标函数;
  15.     # 参数2:需要给函数传的参数是一个元组形式,当需要传的参数是一个时,注意加一个,
  16.     p = Process(target=func,args=('yun',))
  17.     # 2.开启进程,告诉操作系统创建进程,操作系统会去申请一个内存空间,把子进程丢进去执行
  18.     p.start()
  19.     # 3.下面是主进程的执行
  20.     print('主')
复制代码
4.2 创建进程的第二种方式
  1. from multiprocessing import Process
  2. import time
  3. # 1.创建一个类,该类继承Process类
  4. class MyProcess(Process):
  5.     # 2.类中子进程的函数名必须是run
  6.     def run(self):
  7.         print('hello')
  8.         time.sleep(1)
  9.         print('gun')
  10. if __name__ == '__main__':
  11.     # 3.产生类的对象
  12.     p = MyProcess()
  13.     # 4.开启进程
  14.     p.start()
  15.     print('主')
复制代码
总结:
1.创建进程实际上就是在内存中申请了一块内存空间,将代码丢进去运行
2.一个进程产生一个内存空间,多个进程产生多个内存空间
3.进程之间默认是无法进行数据交互的,如果需要交互需要借助第三方模块,在子进程修改全局变量,全局变量不会改变
4.3 进程中join方法

join方法是用来让主进程代码等待调用join的子进程代码运行结束之后,在运行主进程!
  1.     p1.join()
  2.     p2.join()
  3.     p3.join()
  4.     print('主')
  5.     如果p2和p3不调用join方法,主进程就不会等待其运行结束后再运行!!!
复制代码
4.4 进程对象和其他方法

一台计算机上面运行着很多进程,那么计算机是如何区分并管理着这些进程,计算机会给这些进程各自分配一个pid
在windows终端,可以通过tasklist命令查看所有的进程pid
tasklist |findstr PID 查看具体进程的命令
在mac电脑,可以通过ps aux查看
ps aux|grep PID 查看具有进程的命令
进程的其他方法:
  1. from multiprocessing import Process,current_process
  2. import time
  3. import os
  4. def func():
  5.     # current_process().pid 获取当前进程的进程id
  6.     print('%s 正在运行'% current_process().pid)
  7.     time.sleep(2)
  8. if __name__ == '__main__':
  9.     p = Process(target=func)
  10.     p.start()
  11.     # os.getpid()也是获取当前进程id的方法
  12.     p.terminate() # 杀死当前进程,系统帮您杀死该进程,需要一定的时间,所有下面的is_alive可能为true
  13.     print(p.is_alive()) # 判断当前进程是否存活
  14.     print('主',os.getpid())
  15.     # os.getppid()是获取当前父id的方法
  16.     print('主主',os.getppid())
复制代码
4.5 僵尸进程与孤儿进程

僵尸进程:
当子进程死了,子进程并不会立即占用的进程id号,因为需要让父进程查看到子进程的id、运行时间等信息,所有进程会步入僵尸进程
回收子进程的id号:1,负进程调用join()方法 2.父进程等待子进程运行完毕
孤儿进程:
子进程存活,父进程意外死亡。
操作系统会帮你自动回收子进程的资源
4.6 守护进程

"你死我也不独活"  p.daemon = True 方法设置守护进程
  1. from multiprocessing import Process,current_process
  2. import time
  3. def func():
  4.     print('奴隶活着')
  5.     time.sleep(2)
  6.     print('奴隶死去')
  7. if __name__ == '__main__':
  8.     p = Process(target=func)
  9.     p.daemon = True # 将p这个子进程设置成守护进程,这一句话一定要放在start前面,否则保错
  10.     p.start()
  11.     print('主人死了')
复制代码
4.7 进程中的互斥锁

多个进程操作同一个数据的时候,很可能会出现数据错乱的问题
针对上述问题,解决方案就是加锁处理:将并发变成串行,牺牲效率保证数据的安全准确
  1. # 1.导入锁模块
  2. from multiprocessing import Process LOCK
  3. # 2.在主进程中生成一把锁,让所有子进程去抢这把锁,mutex 需要传入对应函数的参数里面
  4. mutex = LOCK()
  5. # 3.在需要加锁的功能上面
  6. mutex.acquire()
  7. # 4.在功能执行完的下面,解锁
  8. mutex.release()
  9. 总结:
  10. 1.锁不要轻易使用,容易造成锁死的现象
  11. 2.锁只在需要争抢数据的时候使用,保证数据的安全
复制代码
4.8 进程间的通信

进程之间是无法相互通信的,因此需要采用第三方模块队列queue。
注意:队列中的数据是先进先出的。
  1. # 导入队列模块
  2. import queue
  3. # 也可以用下面这种方式之间导入到队列类
  4. from multiprocessing import Queue
  5. # 1.生成一个队列对象
  6. q = queue.Queue(3) # 括号内可以传数字,表示队列可以最大存放的数据量,不传有一个很大的默认值
  7. # 2.给队列存数据
  8. q.put(111)
  9. print(q.full()) # 判断当前队列是否存满
  10. q.put(222)
  11. print(q.empty()) # 判断当前队列是否为空
  12. q.put(333)
  13. print(q.full())
  14. # q.put(444) # 当给队列存的数据个数超过队列的最大存放数,队列会进入阻塞状态等待位置
  15. # 3.从队列中取值
  16. v1 = q.get()
  17. v2 = q.get()
  18. v3 = q.get()
  19. # v4  = q.get()  当队列中没有数据的时候,在次取值会使得队列进入阻塞
  20. v5 = q.get_nowait() # 当队列中没有数据可取的时候,就报错
  21. v6 = q.get(timeout=3) # 没有数据原地等待3秒,然后报错
  22. print(v1,v2,v3)
  23. # 总结:
  24. '''
  25. q.full()
  26. q.empty()
  27. q.get_nowait()
  28. 这三个方法在多进程下是不精确的
  29. '''
复制代码
IPC机制:
1.子进程和主进程之间的通信
2.子进程和子进程之间的通信
  1. from multiprocessing import Queue,Process
  2. def cosumer1(q):
  3.     # 在子进程中存数据
  4.     q.put('我是队列存的信息')
  5.     print('子进程1')
  6. def cosumer2(q):
  7.     # 在子进程中取数据
  8.     print(q.get())
  9. if __name__ == '__main__':
  10.     q = Queue()
  11.     p = Process(target=cosumer1,args=(q,))
  12.     p1 = Process(target=cosumer2,args=(q,))
  13.     p.start()
  14.     p1.start()
  15.     # 在主进程取出数据
  16.     # print(q.get())
复制代码
5. 进程的综合应用--生产者消费者模型
  1. from multiprocessing import Queue,Process,JoinableQueue
  2. import time
  3. import random
  4. # 生产者子进程
  5. def producer(name,food,q):
  6.     for i in range(5):
  7.         print('%s生产了%s%s'%(name,food,i))
  8.         time.sleep(random.randint(1,3))
  9.         q.put(food)
  10. def consumer(name,q):
  11.     # 消费者一直在吃,进入循环
  12.     while True:
  13.         food = q.get() # 当队列中没有东西的时候,该子进程会被卡住,进入阻塞状态
  14.         print('%s吃了%s'%(name,food))
  15.         q.task_done() # 该方法属于JoinableQueue,作用是告诉队列你已经从队列中取出一个数据并且处理完毕了
  16. if __name__ == '__main__':
  17.     # 将q = Queue()改成下面的方法创建队列
  18.     q = JoinableQueue()
  19.     # 两个生产者,分别生产的东西放进队列中
  20.     p1 = Process(target=producer,args=('zhang','包子',q))
  21.     p2 = Process(target=producer, args=('yang', '粥', q))
  22.     # 消费者从队列中取出东西吃掉
  23.     c1 = Process(target=consumer,args=('www',q))
  24.     p1.daemon = True  # 守护主进程,主进程结束杀死子进程
  25.     p2.daemon = True
  26.     c1.daemon = True
  27.     p1.start()
  28.     p2.start()
  29.     c1.start()
  30.     p1.join()
  31.     p2.join() # 等待生产者生产完毕在执行下面的代码
  32.     q.join()  # 等待队列中所有的数据被取完之后再执行下述代码
  33.     # JoinableQueue类
  34.     """
  35.     该类是在queue类上的基础上添加了一个计数器,每当往队列中存放一个数据时,计数器会加1;
  36.     当你调用task_done时,计数器减1
  37.     q.join()  等待计数器为0的时候在执行该方法下面的代码
  38.     """
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

泉缘泉

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表