• Python21天学习挑战赛Day(8)·多进程



    ​学习日志5——

    活动地址:CSDN21天学习挑战赛

    1.多进程

            1.1 进程

    程序:xxx.py是程序,是静态的

    进程:一个程序运行起来后,代码+用到的资源 称之为进程,它是操作系统分配资源的基本单元。不仅可以通过线程完成多任务,进程也可以

            1.2进程的状态

     2.进程的创建-multiprocessing

            1.Process类语法

     

    multiprocessing.Process对象具有如下方法和属性 :

            2. 2个while循环一起执行

    1. # -*- coding:utf-8 -*-
    2. from multiprocessing import Process
    3. import time
    4. def run_proc():
    5. """子进程要执行的代码"""
    6. while True:
    7. print("----2----")
    8. time.sleep(1)
    9. if __name__=='__main__':
    10. p = Process(target=run_proc)
    11. p.start()
    12. while True:
    13. print("----1----")
    14. time.sleep(1)

     

             3.进程pid

    1. # -*- coding:utf-8 -*-
    2. from multiprocessing import Process
    3. import os
    4. import time
    5. def run_proc():
    6. """子进程要执行的代码"""
    7. print('子进程运行中,pid=%d...' % os.getpid()) # os.getpid获取当前进程的进程号
    8. print('子进程将要结束...')
    9. if __name__ == '__main__':
    10. print('父进程pid: %d' % os.getpid()) # os.getpid获取当前进程的进程号
    11. p = Process(target=run_proc)
    12. p.start()

     

            4.给子进程指定的函数传递参数 

    1. # -*- coding:utf-8 -*-
    2. from multiprocessing import Process
    3. import os
    4. from time import sleep
    5. def run_proc(name, age, **kwargs):
    6. for i in range(10):
    7. print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
    8. print(kwargs)
    9. sleep(0.2)
    10. if __name__=='__main__':
    11. p = Process(target=run_proc, args=('test',18), kwargs={"m":20})
    12. p.start()
    13. sleep(1) # 1秒中之后,立即结束子进程
    14. p.terminate()
    15. p.join()

             5.进程间不同享全局变量

    1. # -*- coding:utf-8 -*-
    2. from multiprocessing import Process
    3. import os
    4. import time
    5. nums = [11, 22]
    6. def work1():
    7. """子进程要执行的代码"""
    8. print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
    9. for i in range(3):
    10. nums.append(i)
    11. time.sleep(1)
    12. print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))
    13. def work2():
    14. """子进程要执行的代码"""
    15. print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))
    16. if __name__ == '__main__':
    17. p1 = Process(target=work1)
    18. p1.start()
    19. p1.join()
    20. p2 = Process(target=work2)
    21. p2.start()

     3.进程间同步-Queue

            

            1.Queue类语法 

            2.Queue的使用 

     

    1. #coding=utf-8
    2. from multiprocessing import Queue
    3. q=Queue(3) #初始化一个Queue对象,最多可接收三条put消息
    4. q.put("消息1")
    5. q.put("消息2")
    6. print(q.full()) #False
    7. q.put("消息3")
    8. print(q.full()) #True
    9. #因为消息列队已满下面的try都会抛出异常,第一个try会等待2秒后再抛出异常,第二个Try会立刻抛出异常
    10. try:
    11. q.put("消息4",True,2)
    12. except:
    13. print("消息列队已满,现有消息数量:%s"%q.qsize())
    14. try:
    15. q.put_nowait("消息4")
    16. except:
    17. print("消息列队已满,现有消息数量:%s"%q.qsize())
    18. #推荐的方式,先判断消息列队是否已满,再写入
    19. if not q.full():
    20. q.put_nowait("消息4")
    21. #读取消息时,先判断消息列队是否为空,再读取
    22. if not q.empty():
    23. for i in range(q.qsize()):
    24. print(q.get_nowait())

            3.Queue实例 

     

    1. from multiprocessing import Process, Queue
    2. import os, time, random
    3. # 写数据进程执行的代码:
    4. def write(q):
    5. for value in ['A', 'B', 'C']:
    6. print('Put %s to queue...' % value)
    7. q.put(value)
    8. time.sleep(random.random())
    9. # 读数据进程执行的代码:
    10. def read(q):
    11. while True:
    12. if not q.empty():
    13. value = q.get(True)
    14. print('Get %s from queue.' % value)
    15. time.sleep(random.random())
    16. else:
    17. break
    18. if __name__=='__main__':
    19. # 父进程创建Queue,并传给各个子进程:
    20. q = Queue()
    21. pw = Process(target=write, args=(q,))
    22. pr = Process(target=read, args=(q,))
    23. # 启动子进程pw,写入:
    24. pw.start()
    25. # 等待pw结束:
    26. pw.join()
    27. # 启动子进程pr,读取:
    28. pr.start()
    29. pr.join()
    30. # pr进程里是死循环,无法等待其结束,只能强行终止:
    31. print('')
    32. print('所有数据都写入并且读完')

    4.进程间同步-Lock 

             2.程序不加锁

    1. import multiprocessing
    2. import time
    3. def add(num, value):
    4. print('add{0}:num={1}'.format(value, num))
    5. for i in range(0, 2):
    6. num += value
    7. print('add{0}:num={1}'.format(value, num))
    8. time.sleep(1)
    9. if __name__ == '__main__':
    10. lock = multiprocessing.Lock()
    11. num = 0
    12. p1 = multiprocessing.Process(target=add, args=(num, 1))
    13. p2 = multiprocessing.Process(target=add, args=(num, 2))
    14. p1.start()
    15. p2.start()

    运行结果:运行无顺序,进程交替进行

             3.程序加锁

    1. import multiprocessing
    2. import time
    3. def add(num, value, lock):
    4. try:
    5. lock.acquire()
    6. print('add{0}:num={1}'.format(value, num))
    7. for i in range(0, 2):
    8. num += value
    9. print('add{0}:num={1}'.format(value, num))
    10. time.sleep(1)
    11. except Exception as err:
    12. raise err
    13. finally:
    14. lock.release()
    15. if __name__ == '__main__':
    16. lock = multiprocessing.Lock()
    17. num = 0
    18. p1 = multiprocessing.Process(target=add, args=(num, 1, lock))
    19. p2 = multiprocessing.Process(target=add, args=(num, 2, lock))
    20. p1.start()
    21. p2.start()

    运行结果:只有其中一个进程执行完成后,其它进程才会执行,且谁先抢到,谁先执行

    5.进程池Pool 

         1.Pool类语法

     multiprocessing.Pool常用函数:

             2.Pool实例

    1. # -*- coding:utf-8 -*-
    2. from multiprocessing import Pool
    3. import os, time, random
    4. def worker(msg):
    5. t_start = time.time()
    6. print("%s开始执行,进程号为%d" % (msg,os.getpid()))
    7. # random.random()随机生成0~1之间的浮点数
    8. time.sleep(random.random()*2)
    9. t_stop = time.time()
    10. print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))
    11. po = Pool(3) # 定义一个进程池,最大进程数3
    12. for i in range(0,10):
    13. # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
    14. # 每次循环将会用空闲出来的子进程去调用目标
    15. po.apply_async(worker,(i,))
    16. print("----start----")
    17. po.close() # 关闭进程池,关闭后po不再接收新的请求
    18. po.join() # 等待po中所有子进程执行完成,必须放在close语句之后
    19. print("-----end-----")

     

     

            3.进程池中的Queue

     

    1. # -*- coding:utf-8 -*-
    2. # 修改import中的Queue为Manager
    3. from multiprocessing import Manager,Pool
    4. import os,time,random
    5. def reader(q):
    6. print("reader启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    7. for i in range(q.qsize()):
    8. print("reader从Queue获取到消息:%s" % q.get(True))
    9. def writer(q):
    10. print("writer启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
    11. for i in "itcast":
    12. q.put(i)
    13. if __name__=="__main__":
    14. print("(%s) start" % os.getpid())
    15. q = Manager().Queue() # 使用Manager中的Queue
    16. po = Pool()
    17. po.apply_async(writer, (q,))
    18. time.sleep(1) # 先让上面的任务向Queue存入数据,然后再让下面的任务开始从中取数据
    19. po.apply_async(reader, (q,))
    20. po.close()
    21. po.join()
    22. print("(%s) End" % os.getpid())

    6.进程,线程对比 

            1.功能

     

            2.区别 

            3.优缺点 

     

  • 相关阅读:
    【13】加法器:如何像搭乐高一样搭电路(上)?
    【Proteus仿真】【STM32单片机】防火防盗GSM智能家居设计
    Python中判断字母数字的方法合集
    rhcsa(rh134)
    使用OfficeTool免费安装Office
    设计模式-综合应用(一)
    【MySQL】一文带你了解MySQL的基础知识
    【Java面试】听说Java求职者/面试官都关注了我,这道面试题一个空Object对象的占多大空间?你答的上来吗
    IDEA怎么将CRLF转化为LF
    Linux环境安装一:jdk的安装及将jar包项目发布在服务器上
  • 原文地址:https://blog.csdn.net/weixin_62599885/article/details/126235481