Python: 多线程和多进程

  • 什么是进程?什么是线程?

    • 进程: 可以简单地认为是一个程序. 进程是操作系统分配资源的最小单位.
    • 线程: 一个进程可以有多个线程, 每个线程可以独立完成一些任务. 线程是操作系统进行运算调度的最小单位.
  • 多线程demo

    from threading import Thread    
    for i in range(10):
        # 只是创建了线程对象
        t = Thread(target=request_baidu)
        # 启动线程
        t.start()
    
  • 多进程demo

    from multiprocessing import Process   
    for i in range(10):
        # 只是创建了进程对象
        p = Process(target=request_baidu)
        # 启动进程
        p.start()
    
  • 多线程

    • 等待任务完成后回到主进程

      通过调用Thread对象的join方法

      # 保存当前thread对象
      thread_array = []
      for i in range(10):
          t = Thread(target=request_baidu, args=(i, ))
          thread_array.append(t)
          t.start()
      # 调用thread对象join接口, 等待任务完成后回到主进程
      for t in thread_array:
          t.join()
      print("done!")
      
    • 如何拿到返回结果

      • 赋值到全局变量当中, 添加到可变对象之中

        result = []
        def request_baidu(index):
        	...
            result.append(response)
            
        if __name__ == "__main__":
            thread_array = []
            for i in range(10):
                t = Thread(target=request_baidu, args=(i, ))
                thread_array.append(t)
                t.start()
            for t in thread_array:
                t.join()
            print("done!")
            print(result)
        
  • 多进程

    • 等待任务完成后回到主进程

      通过调用Process对象的join方法

    • 如何拿到返回结果

      无法通过全局变量存储返回结果.

      多进程相当于启动了多个程序, 共同执行了同一份代码, 他们之间的内存地址完全不一样

      import requests
      import time
      from threading import Thread
      from multiprocessing import Process
      
      result = []
      print(f"主进程result内存地址: {id(result)}")
      
      def request_baidu(index):
          time.sleep(2)
          url = "https://www.baidu.com/"
          # body = ""
          headers = {
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
          }
          response = requests.get(url=url, headers=headers)
          print(f"当前请求序号: {index}, 返回结果状态码: {response.status_code}")
          print(f"子进程result内存地址: {id(result)}")
          result.append(response)
      
      # 如果没有判断入口代码段if __name__ == "__main__", 多进程程序会报错
      # 原因是windows和pycharm的进程阻塞带来的问题
      if __name__ == "__main__":
          process_array = []
          for i in range(10):
              p = Process(target=request_baidu, args=(i, ))
              process_array.append(p)
              p.start()
          for p in process_array:
              p.join()
          print("done!")
          print(result)
      
  • 多进程和多线程的异同点

    • 相同点

      • 都是对cpu工作时间段的描述, 只是颗粒度不同.

        简单地说就是多进程和多线程都会调用cpu资源的, 但是进程可以启动多个线程去执行.

      • linux内核态不区分进程和线程

    • 不同点

      • 进程有自己的独立地址空间, 建立数据表来维护代码段, 堆栈段和数据段, 而线程共享进程中的资源, 使用相同的地址空间, 所以线程间的切换快得多.
      • 因为线程共享进程的全局变量, 静态变量等对象, 线程间的通信更为方便, 而进程间的通信更加复杂, 需要以ipc的方式进行.
      • 多进程要比多线程要健壮. 进程之间一般不会相互影响, 而多线程有一条线程崩溃, 会导致整个进程跟着发生崩溃或者无法正常退出等.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值