最近因为工作的需要,涉及到了python多进程、多线程相关内容,在此做个简单的记录,内容为个人的理解和梳理,如果有不对的地方,还请大家及时批评指正!
进程
进程,通俗的讲就是正在执行的一个程序,运行一个进程就是启动一个程序,多进程就是CPU同时让多个进程(或者理解为任务、程序)交替往复的执行,只是因为CPU执行速度太快,给我们的感觉就像是所有任务都在同时执行。
多进程
在Python语言中,每开一个进程,都会“获取”CPU部分的内存资源、地址空间,各个进程之间的资源、空间都是相对独立的,互不干扰,多进程之间默认是不进行信息交互的,子进程是依赖于父进程的,各个子进程之间依然是相互独立的,同样默认不进行信息交互,我们可以通过以下这张图来加深理解
进程的Python语言实现
在Python中我们通过Process这个包来创建进程
from multiprocessing import Process
来看一个非常简单的小例子
from multiprocessing import Process
def run(name):
print("子进程运行中, name = %s"%(name))
if __name__ == '__main__': # 这相当于创建了一个父进程
print("父进程启动")
p = Process(target=run, args=("test",)) # 进程当做对象(即可以有属性),target是目标函数,args跟所调函数的参数
print("子进程将要执行")
p.start() # 子进程启动,实际是调用了Process中的.run()方法
print(p.name) # .name表示当前进程的名字
p.join() # 因为子进程依赖于父进程,父进程结束子进程也就结束,.join可以实现让父进程等待子进程运行结束
print("子进程结束")
我们来看一下运行结果
父进程启动
子进程将要执行
Process-1
子进程运行中, name = test
子进程结束
进程的Python语言实现
from multiprocessing import Process
def write():
for i in range(10):
print("写博客")
time.sleep(1)
def watch():
for i in range(10):
print("看球赛")
time.sleep(1)
if __name__ == '__main__':
p1 = Process(target=write, name="进程1")
p2 = Process(target=watch)
p1.start()
p2.start()
p1.is_alive() # 判断是否该进程是否在运行,运行则返回True
p1.join()
p2.join()
运行效果
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
写博客
看球赛
......
正如之前所说,多进程实际是交替执行的,但是因为CPU执行速度太快,给我们的感觉就是同时运行了,加个休眠time.sleep()可以很好的看出这一点
进程之间的通信
我们知道Python进程之间是相互独立,默认没有信息交互的,注意默认这两个字,也就是说,如果需要,我们仍然是可以进行信息交互的,那就需要借助外部“工具”了
from multiprocessing import Queue
Queue队列就是我们的工具,我们简单看一下这个工具能为我们提供哪些帮助
q = Queue(3) # 初始化Queue对象,最多可接收3条消息
Queue.qsize() # 返回当前队列包含的消息数量
Queue.empty() # 队列为空返回True,反之False
Queue.full() # 判断队列是否满了,True和False
Queue.get([block[,timeout]]) # 获取队列消息,后移除block默认为True
# 采用默认值时,若没设置timeout,此时队列若为空,程序将被阻塞(一直停留在get),如果设置了timeout
# 等待完成后则抛出异常提示
Queue.put(item,[block[,timeout]]) # 将item消息写入队列
我们再通过一个简单的例子来了解一下如何应用队列来进行进程之间的信息交互
from multiprocessing import Process, Queue
def pass_(q):
for player in ["詹姆斯", "戴维斯", "库兹马"]:
print("隆多传球给:", player)
q.put(player)
time.sleep(1)
def shoot(q):
while True:
if not q.empty():
print("出手绝杀的是", q.get())
time.sleep(1)
else:
break
if __name__ == '__main__':
q = Queue()
pw = Process(target=pass_, args=(q,))
pr = Process(target=shoot, args=(q,))
pw.start()
pw.join()
pr.start()
pr.join()
print("湖人总冠军!")
让我们来揭晓结果!
隆多传球给: 詹姆斯
隆多传球给: 戴维斯
隆多传球给: 库兹马
出手绝杀的是 詹姆斯
出手绝杀的是 戴维斯
出手绝杀的是 库兹马
湖人总冠军!