【python】进阶--->并发编程之进程
在介绍进程之前,我先给大家介绍一些有用的概念
一、并发编程
多任务:操作系统同时运行多个任务
并行和并发 :
并行 : 指任务数小于等于cpu核数,同一时刻,有多条指令在多个处理器上同时执行
并发 : 指任务数量大于cpu核数,同一时刻只有一条指令执行,但是多个指令被快速的轮换执行,使得具有多个任务同时执行的效果.
二、进程
编写完毕的代码,在没有运行的时候,称之为程序.正在运行的代码,就成为了进程.
操作系统是通过进程去完成一个一个的任务,进程是管理事务的基本单元,也是操作系统分配资源的基本单元.
进程拥有自己的独立环境(当前需要用到那些环境变量,程序运行的目录,当前是哪个用户在运行此程序等)和系统资源(处理器占用率,存储器,数据等等)
1、进程的生命周期
2、进程调度
要想多个进程交替运行,操作系统必须对这些进程进行调度,这个调度不是随机进行的,而是遵循一定的法则:进程的调度算法
- 先来先服务调度算法
- 短作业优先调度算法
- 时间片轮转法
- 多级反馈队列
# 就绪状态,等待操作系统调度开始运行
import time # 运行
print('程序开始运行') # 运行
name = input('请输入:') # 阻塞
# 就绪状态
print(name) # 运行
time.sleep(1) # 阻塞
# 就绪状态
print('程序结束运行') # 运行
# 结束
就绪:当进程已经分配到除了cpu之外的所有必要的资源,只要获得cpu的调用即可立即执行.
执行:当程序已经获取cpu,正在cpu上运行
阻塞:由于等待某个事件发生而无法执行,便放弃cpu处于阻塞状态.引进阻塞的事件:等待i/o操作,申请的缓冲区不能满足,等待信号等等.
3、主进程和子进程
在并发编程中,当一个程序启动后,产生的进程就是主进程,之后新建的进程称为子进程
Process(group, target, name, args, kwargs)
group : 指定进程序组,不需要
target : 子进程需要执行的代码,传递函数的名字
name : 给进程设定一个名字,可以不设定.
默认为Process-N(N为从1开始递增的整数)
args : 给target指定的函数传递的参数,以元组的形式
kwargs : 给target指定的函数传递的参数,以字典的形式
4、Process创建的对象常用方法:
start() : 启动子进程
is_alive() : 判断进程子进程是否还活着
join(timeout) : 是否等待子进程执行结束,或者等待多少秒.
terminate() : 不论任务是否完成,立即终止子进程
from multiprocessing import Process
import time
import os
def test1():
while True:
print('test1-----')
time.sleep(1)
def test2():
while True:
print('test2-----')
time.sleep(1)
# 进程的创建1
# if __name__ == '__main__':
# # 主进程
# print('主进程开始')
# p1 = Process(target=test1)
# p2 = Process(target=test2)
# print(p1.name)
# print(p2.name)
# # 启动进程
# p1.start()
# p2.start()
# 进程的创建2
class ProcessClass(Process):
def __init__(self):
super().__init__()
def run(self):
# os.getpid():获取当前进程pid
# os.getppid():获取当前进程父进程pid
t_start = time.time()
print('子进程(%s)开始执行,父进程(%s)' %
(os.getpid(), os.getppid()))
time.sleep(2)
t_end = time.time()
print('(%s)执行结束,耗时%0.2f秒' % (os.getpid(), t_end-t_start))
if __name__ == '__main__':
t_start = time.time()
print('当前进程(%s)' % os.getpid()) # 主进程
p1 = ProcessClass()
p1.start()
# 对于不包含target属性的Processs类的对象执行start方法,
# 就会运行这个类中的run方法
p1.join() # 阻塞直到p1进程执行完毕再结束阻塞
t_stop = time.time()
print('(%s)执行结束,耗时%0.2f' % (os.getpid(), t_stop-t_start))
5、进程间不同享全局变量
from multiprocessing import Process
# def test(*args, **kwargs):
# print(args, kwargs)
#
#
# if __name__ == '__main__':
# p = Process(target=test, args=(1, ), kwargs={'name': 'wuluo'})
# p.start()
list1 = [1, 2, 3, 4]
def test1():
list1.append(5)
print('test1---', list1)
def test2():
print('test2---', list1)
if __name__ == '__main__':
p1 = Process(target=test1)
p1.start()
p1.join()
p2 = Process(target=test2)
p2.start()
6、进程间的通信Queue()
进程是一个独立的资源分配单元,不同进程之间的资源是独立的,不能在一个进程中直接访问另一个进程的资源.但是不同的进程之间需要进行信息的交互和状态的传递等等,因此,需要进程间的通信.
Queue() : 括号内部没有指定最大可接受的消息数量,或者数字为负数,那么代表可接受的消息数量没有上限(内存的尽头)
Queue.put(item,block, timeout) : 将item写入消息队列.block默认为True
?如果block使用默认值True,且没有设置timeout秒.消息队列如果没有空间可写入,将被阻塞,直到队列腾出空间为止.
?如果设置了timeout秒,则会等待timeout秒,若还没有空间,则抛出queue.full异常.
?如果block设置为False,消息队列没有空间可写入,则会立即抛出queue.full异常.
import multiprocessing
q = multiprocessing.Queue(3) # 括号内表示最多接收的消息数
q.put('消息1')
q.put('消息2')
q.put('消息3')
q.put('消息4', block=False) # 当队列满了之后,会阻塞,不能写入
关于Python进程的介绍今天就到这里啦,后续我会为大家介绍线程以及协程的相关知识哦~
关注我,带你领略Python的风采~😍😍😍
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!