15.Python的多进程与多线程

多进程与多线程

  • 15.Python的多进程与多线程

进程

  • 什么是进程
    • 进程就是程序执行的载体
  • 进程在生活中的应用
    • 打开QQ
    • 打开微信
    • 玩游戏
    • 我们打开的每个软件/游戏,执行的每一个Python脚本都是启动一个进程
    • 软件(游戏/脚本)===进程
  • 进程的口粮
    • 每一个进程像人一样需要吃饭,他的粮食就是:CPU和内存
    • 15.Python的多进程与多线程
  • 多进程
    • 15.Python的多进程与多线程
    • 同时启动多个软件(进程),多个进程同时在执行程序,他们之间互不干扰,各自执行自己的业务逻辑。
  • 多进程的执行方式
    • 15.Python的多进程与多线程

线程

  • 什么是线程
    • 15.Python的多进程与多线程
  • 线程和进程的关系
    • 进程提供线程执行程序的前提要求,线程在重组的资源配备下,去执行程序。
  • 多线程
    • 15.Python的多进程与多线程
    • 开启一个浏览器进程后,从浏览器(主线程)中创建出多个线程来开启多个页面
  • 多线程的执行方式
    • 15.Python的多进程与多线程

进程的创建

  • 进程的创建模块--multiprocessing

    • 函数名 介绍 参数 返回值
      Process 创建一个进程 target,args 进程对象
    • 函数名 介绍 参数 返回值
      start 执行进程
      join 阻塞程序
      kill 杀死进程
      is_alive 进程是否存活 bool
    • 示例代码:

      • import time
        import os
        import multiprocessing
        
        
        def work_a():
            for i in range(10):
                print(i, ‘a‘, os.getpid())
                time.sleep(1)
        
        
        def work_b():
            for i in range(10):
                print(i, ‘b‘, os.getpid())
                time.sleep(1)
        
        
        if __name__ == ‘__main__‘:
            start = time.time()
        
            a = multiprocessing.Process(target=work_a)
            # a.start()
        
            b = multiprocessing.Process(target=work_b)
            # b.start()
        
            print(time.time() - start)
        
            # 用for循环创建
            for p in (a, b):
                p.start()
        
  • 多进程的问题

    • 通过进程模块执行的函数无法获取返回值
    • 多个进程同时修改文件可能会出现错误
    • 进程数量太多可能会造成资源不足,甚至死机等情况。

进程池与进程锁

  • 什么是进程池

    • 15.Python的多进程与多线程
    • 避免了创建于关闭的消耗
  • 进程池的创建---multiprocessing

    • 函数名 介绍 参数 返回值
      Pool 进程池创建 Processcount 进程池对象
    • 函数 介绍 参数 返回值
      Apply_async 任务加入进程池(异步) func,args
      close 关闭进程池
      Join 等待进程池任务结束
    • 示例代码:

      • import multiprocessing
        import os
        import time
        
        
        def work(count):
            print(count, os.getpid())
            time.sleep(5)
        
        
        if __name__ == ‘__main__‘:
            pool = multiprocessing.Pool(5)
        
            for i in range(20):
                pool.apply_async(func=work, args=(i,))
        
            time.sleep(20)
        
  • 进程锁

    • 15.Python的多进程与多线程
  • 进程锁的用法

    • from multiprocessing import Manager
      manage=Manager()
      lock=manage.Lock()
      
    • 函数名 介绍 参数 返回值
      acquire 上锁
      release 开锁(解锁)

进程的通信

  • 什么是进程的通信

    • 15.Python的多进程与多线程
  • 队列的创建-multiprocessing

    • 函数名 介绍 参数 返回值
      Queue 队列的创建 mac_cout 队列对象
    • 函数名 介绍 参数 返回值
      put 消息放入队列 message
      get 获取队列消息 str

线程的创建

  • 线程的创建--threading

    • 方法名 说明 举例
      Thread 创建线程 Thread(target,args)
  • 线程对象的方法

    • 方法名 说明 用法
      start 启动线程 start()
      join 阻塞直到线程执行结束 join(timeour=None)
      getName 获取线程的名字 getName()
      setName 设置线程的名字 setName(name)
      is_alive 判断线程是否存活 is_alive()
      setDeamon 守护线程 setDeamon(True)
  • 线程的问题

    • 通过线程执行的函数无法获取返回值
    • 多个线程同时修改文件可能造成数据错乱
  • 示例代码:

    • import time
      import random
      import threading
      
      lists = [‘python‘, ‘django‘, ‘tronado‘,
               ‘flask‘, ‘bs5‘, ‘requests‘]
      
      new_lists = []
      
      
      def work():
          if len(lists) == 0:
              return
          data = random.choice(lists)
          lists.remove(data)
          new_data = ‘%s_new‘ % data
          new_lists.append(new_data)
          time.sleep(1)
      
      
      if __name__ == ‘__main__‘:
          start = time.time()
          t_list = []
          for i in range(len(lists)):
              t = threading.Thread(target=work)
              t_list.append(t)
              t.start()
      
          for t in t_list:
              t.join()
          print(‘old list‘, lists)
          print(‘new list‘, new_lists)
          print(‘time is %s‘ % (time.time() - start))
      

线程池的创建

  • 线程池---concurrent

    • 方法名 说明 举例
      futures.ThreadPoolExecutor 创建线程池 tpool=ThreadPoolExecutor(max_workers)
  • 线程池---concurrent

    • 方法名 说明 用法
      submit 往线程池中加入任务 submit(target,args)
      done 线程池中的某个线程是否完成了任务 done()
      result 获取当前线程执行任务的结果 result()
  • 示例代码

    • import time
      import os
      import threading
      from concurrent.futures import ThreadPoolExecutor
      
      lock = threading.Lock()
      
      
      def work(i):
          lock.acquire()
          time.sleep(1)
          lock.release()
          return ‘result %s‘ % i
      
      
      if __name__ == ‘__main__‘:
          print(os.getpid())
          t = ThreadPoolExecutor(2)
          result = []
      
          for i in range(20):
              t_result = t.submit(work, (i,))
              result.append(t_result)
          for res in result:
              print(res.result())
      
      

认识GIL全局锁

  • 别家的线程与我家的线程
    • 15.Python的多进程与多线程
  • Gil的作用
    • 单一cpu工作
    • 线程安全
    • pypy
    • 多进程+多线程

初探异步

  • 什么是异步与异步的好处

    • 15.Python的多进程与多线程
  • 异步与多线程多进程

    • 轻量级的线程 协程
    • 可以获取异步函数的返回值
    • 主进程需要异步才行
    • 更适合文件读写使用
  • async,await与asyncio模块

    • async定义异步

      • async def test():
          return ‘a‘
        
    • await执行异步

      • async def handle():
          result = await test()
        
  • asyncio调用async函数

    • 函数名 介绍 参数 返回值
      gather 将异步函数批量执行 Asyncfunc.. List函数的返回结果
      run 执行主异步函数 [task] 执行函数的返回结果
    • import asyncio
      
      
      async def main():
          result = await  asyncio.gather(a(), b())
          print(result)
      
      
      if __name__ == ‘__main__‘:
          asyncio.run(main())
      
  • gevent

    • Pip install gevent
    • Microsoft Visual C++
    • Pip install wheel
  • gevent模块常用方法

    • 函数名 介绍 参数 返回值
      spawn 创建协程对象 Func,args 协程对象
      joinall 批量处理协程对象 [spawnobj] [spawnobj]
  • gevent协程对象的方法

    • 函数名 介绍 参数 返回值
      get(value) 获取异步程序结果 函数的返回值
      join 阻塞等待异步程序结束
      kill 杀掉当前协程
      Dead 判断协程是否消失 bool

15.Python的多进程与多线程

上一篇:linux保存每个登录用户命令记录


下一篇:CSP 提高初赛个人复习点小结