目录
程序与进程的区别:
程序:程序是静态的。(就是相当于一个文本文件)
进程:将程序加载到内存之后,加上需要用到的资源就称之为进程,是操作系统分配资源的基本单位。
多进程的例子:
"""
程序目标:演示多进程(系统分配的进程号,给进程指定的名字(别名)、)、立即结束子进程、join方法
主要步骤:
1.创建两个函数
2.在主函数中创建两个子进程
"""
import time
import os
import multiprocessing
def say_one(*args, **kwargs):
print("给子进程指定的别名是: ", args[0])
print("给子进程一个幸运的数字吧:",args[1])
print("给子进程传递的键值对是: ",kwargs)
for i in range(5):
print("--------say_one: ",os.getpid(), " 次数: ", i)
time.sleep(0.5)
def say_two():
for i in range(5)
print("--------say_two: ",os.getpid()," 次数: ", i)
time.sleep(0.5)
# 用来测试 join方法(join可以设置时间参数)
time(10)
print("当我调用join方法的时候只有等我结束了,下面才能继续运行")
def main():
# 创建两个子进程
t1 = multiprocessing.Process(target=say_one, args=("one_pro", 15), kwargs={"gg":20})
t2 = multiprocessing.Process(target=say_two)
# 开始执行两个子线程
t1.start()
t2.start()
# 等待1.5s
time.sleep(1.5)
# 不管子进程1是否完成,立即终止
t1.terminate()
# 在测试的时候没有加上这个语句出现了我不想要的结果:可能的原因是,在执行上面这个语句取关闭进程1的时候
# 此时还没有完成关闭的这个动作,主进程已经在执行下面的判断语句了。让它暂停0.1s也就能看到想要的结果
time.sleep(0.1)
# 判断两个进程是否存在:
if t1.is_alive():
print("子进程1是还活着: ",)
else:
print("子进程1已经死亡")
if t2.is_alive():
print("子进程2是还活着: ",)
else:
print("子进程2已经死亡")
t2.join()
print("由于上面调用的join方法,我只能等待它完成了,我才能继续运行(注意等待的时间)")
if __name__ == "__main__":
main()
多进程:不共享全局变量:
"""
程序的目的:验证多进程不共享全局变量
"""
import multiprocessing
import time
def alter_g_list():
global g_list
for i in range(5):
g_list.append(33)
time.sleep(0.3)
print(g_list)
def change_g_list():
global g_list
for i in range(5):
g_list.append(44)
time.sleep(0.5)
print(g_list)
g_list = [1,2]
def main():
t1 = multiprocessing.Process(target=alter_g_list)
t1.start()
t1.join()
t2 = multiprocessing.Process(target=change_g_list)
t2.start()
t2.join()
print(g_list)
if __name__ == "__main__":
main()
多进程之间的通信:queue
"""
程序的目标: 使用queue队列实现进程之间的通信
可以使用multiprocessing中Queue来实现多进程之间的通信
Queue 的简单使用:
初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);
Queue.qsize():返回当前队列包含的消息数量;
Queue.empty():如果队列为空,返回True,反之False ;
Queue.full():如果队列满了,返回True,反之False;
Queue.get([block[, timeout]]):获取队列中的一条消息,然后将其从列队中移除,block默认值为True;
1)如果block使用默认值,且没有设置timeout(单位秒),消息列队如果为空,此时程序将被阻塞(停在读取状态),直到从消息列队读到消息为止,如果设置了timeout,则会等待timeout秒,若还没读取到任何消息,则抛出"Queue.Empty"异常;
2)如果block值为False,消息列队如果为空,则会立刻抛出"Queue.Empty"异常;
Queue.get_nowait():相当Queue.get(False);
Queue.put(item,[block[, timeout]]):将item消息写入队列,block默认值为True;
1)如果block使用默认值,且没有设置timeout(单位秒),消息列队如果已经没有空间可写入,此时程序将被阻塞(停在写入状态),直到从消息列队腾出空间为止,如果设置了timeout,则会等待timeout秒,若还没空间,则抛出"Queue.Full"异常;
2)如果block值为False,消息列队如果没有空间可写入,则会立刻抛出"Queue.Full"异常;
Queue.put_nowait(item):相当Queue.put(item, False);
"""
import multiprocessing
import time
def write_data(q):
for i in range(5)
q.put(i)
time.sleep(0.4)
def read_data(q):
while not q.empty()
value = q.get()
print("在队列中取到的值为:", value)
def main():
q = multiprocessing.Queue()
t1 = multiprocessing.Process(target=write_data, args=(q,))
t2 = multiprocessing.Process(target=read_data, args=(q,))
t1.start()
t1.join()
t2.start()
if __name__ == "__main__":
main()
进程池:
"""
程序的目标:演示multiprocessing.Pool的使用
关于进程池:
始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,
那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,
那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务,
"""
import multiprocessing
import os
import time
import random
def test_work(*args, **kwargs):
print("进程号为:", os.getpid()," 是主进程创建的%d个进程 "% args[0])
time.sleep(random.randint(0, 2))
def main():
# 进程池最多只能容纳4个进程
my_pool = multiprocessing.Pool(4)
# 往进程池里面仍进程
for i in range(10):
# 如果池子满了,就会等待
my_pool.apply_async(test_work, (i,))
# 等前面的进程处理完了,后面的进程也都扔进池子里面去了,就可以关闭进程池
my_pool.close()
# 关闭池子并不意味池子里面的而进程处理完成了,仅仅意味已经池子不接收任何的进程了
# 在进程池中主进程不会等待池子里面的进程处理完,所以要等待里面的进程都处理完成
my_pool.join()
print("------你们先走吧,我垫后 --------")
if __name__ == "__main__":
main()
进程池中进程的通信:(???)
import multiprocessing
import time
def my_write(queue):
for i in "sometime":
queue.put(i)
def my_read(queue):
for i in range(queue.qsize()):
print(queue.get())
def main():
# 创建一个队列.
queue = multiprocessing.Manager().Queue()
# 创建进程池
po = multiprocessing.Pool()
# 往进程池里仍进程
po.apply_async(my_write, args=(queue,))
time.sleep(2)
po.apply_async(my_read, args=(queue,))
# 关闭进程池
po.close()
# 等待进程池中的进程完成
po.join()
if __name__ == "__main__":
main()