Day-26 多线程和多进程

Day-26 多线程和多进程

  1. 线程类子类的用法

    • 创建线程类的子类

    • 实现run方法确定线程任务

    • 如果现实子线程中的任务需要额外的数据, 数据通过对象属性来提供

    • from threading import Thread, current_thread
      import time
      
      # 1. 创建线程类的子类
      class  DownloadThread(Thread):
          # 3. 如果现实子线程中的任务需要额外的数据, 数据通过对象属性来提供
          def __init__(self, name):
              super().__init__()
              self.m_name = name
      
      
          # 2. 实现run方法确定线程任务
          def run(self) -> None:
              print(f'开始下载:{self.m_name}')
              print(current_thread())
              time.sleep(2)
              print(f'{self.m_name}结束下载')
      
      
      print('外面:', current_thread())
      
      t1 = DownloadThread('天堂电影院')
      t1.start()
      
  2. 多线程图片的下载

    • import requests
      from threading import Thread
      
      
      def get_image_url():
          """
          获取所有图片的地址
          :return:
          """
          url = 'https://rt.huashi6.com/front/works/rank_page'
          response = requests.get(url)
          if response.status_code == 200:
              result = response.json()
              for data in result['data']['works']['datas']:
                  yield 'https://img2.huashi6.com/' + data['coverImage']['path']
          else:
              print('数据获取失败')
      
      
      class DownloadImageThread(Thread):
          def __init__(self, image_url: str):
              super(DownloadImageThread, self).__init__()
              self.image_url = image_url
      
          def run(self) -> None:
              response = requests.get(self.image_url)
              image_name = self.image_url.split("/")[-1]
              if response.status_code == 200:
                  with open(f'files/{image_name}', 'wb') as f:
                      f.write(response.content)
              else:
                  print(f'{image_name}下载失败!')
      
      
      if __name__ == '__main__':
          all_image_url = get_image_url()
          for url in all_image_url:
              t = DownloadImageThread(url)
              t.start()
      
  3. join的用法

    • from datetime import datetime
      import time
      from threading import Thread
      from random import randint
      
      
      def download(name):
          print(f'{name}开始下载:{datetime.now()}')
          time.sleep(randint(2, 5))
          print(f'{name}下载结束:{datetime.now()}')
      
      
      def wait():
          t1.join()
          t2.join()
          t3.join()
          print('======================下载完成======================')
      
      
      if __name__ == '__main__':
          t1 = Thread(target=download, args=('肖申克的救赎',))
          t2 = Thread(target=download, args=('霸王别姬', ))
          t3 = Thread(target=download, args=('阿甘正传',))
      
          # 线程对象.join()  -  join操作后面的代码只有在线程对象的任务完成后才会执行
          # =============情况1:三个电影都下载结束才打印'电影下载结束'=============
          # t1.start()
          # t2.start()
          # t3.start()
          # t1.join()
          # t2.join()
          # t3.join()
          # print('电影下载结束!')
      
          # =============情况2:第一个电影下载结束后另外两个电影才同时才是下载=============
          # t1.start()
          # t1.join()
          # t2.start()
          # t3.start()
      
          # =============情况3: 在某个子线程中等三个电影结束打印'下载完成'=================
          t1.start()
          t2.start()
          t3.start()
          t4 = Thread(target=wait)
          t4.start()
          while True:
              input('请输入数据:')
      
  4. 多进程

    • 一个应用程序默认有一个进程(主进程), 这个进程中默认有一个线程(主线程)

    • 一个进程中可以有多个线程

    • 一个应用程序可以有多个进程

    • from multiprocessing import Process
      # Process是进程类, 在需要额外的进程的时候就创建爱你Process的对象
      
      from datetime import datetime
      import time
      from threading import Thread
      from random import randint
      
      
      def download(name):
          print(f'{name}开始下载:{datetime.now()}')
          time.sleep(randint(2, 5))
          print(f'{name}下载结束:{datetime.now()}')
      
      if __name__ == '__main__':
          p1 = Process(target=download, args=('触不可及',))
          p2 = Process(target=download, args=('恐怖游轮',))
          p3 = Process(target=download, args=('大佛Plus',))
          p1.start()
          p2.start()
          p3.start()
      
  5. 进程中的多线程

    • from datetime import datetime
      import time
      from threading import Thread, current_thread
      from random import randint
      from multiprocessing import Process, current_process
      
      
      def download(name):
          print(f'{name}开始下载:{datetime.now()}')
          print(f'当前进程:{current_process()}')
          print(f'当前线程:{current_thread()}')
          time.sleep(randint(2, 5))
          print(f'{name}下载结束:{datetime.now()}')
      
      def assigning_task():
          t1 = Thread(target=download, args=('肖申克的救赎',))
          t2 = Thread(target=download, args=('霸王别姬',))
          t3= Thread(target=download, args=('阿甘正传',))
          t1.start()
          t2.start()
          t3.start()
      
      if __name__ == '__main__':
          # 1. 在主进程的主线程中执行
          # download('霸王别姬')
          # download('hengbagui')
          # download('阿甘正传')
      
          # 2. 在主进程的三个子线程中执行
          # t1 = Thread(target=download, args=('肖申克的救赎',))
          # t2 = Thread(target=download, args=('霸王别姬',))
          # t3= Thread(target=download, args=('阿甘正传',))
          # t1.start()
          # t2.start()
          # t3.start()
      
          # 3. 在三个子进程的主线程中执行
          # p1 = Process(target=download, args=('肖申克的救赎',))
          # p2 = Process(target=download, args=('霸王别姬',))
          # p3 = Process(target=download, args=('阿甘正传',))
          # p1.start()
          # p2.start()
          # p3.start()
      
          # 4. 在一个子进程中的三个字线程中执行
          p1 = Process(target=assigning_task)
          p1.start()
      
  6. 线程的数据共享

    • from datetime import datetime
      import time
      from threading import Thread, current_thread
      from random import randint
      from multiprocessing import Process, current_process, Queue
      
      
      
      def download(name, q: Queue):
          print(f'{name}开始下载:{datetime.now()}')
          time.sleep(randint(2, 5))
          print(f'{name}下载结束:{datetime.now()}')
          q.put(f'{name}数据')
      
      
      def add_task(q: Queue):
          for index in range(1, 11):
              t = Thread(target=download, args=(f'电影{index}', q))
              t.start()
      
      
      def get_data(q: Queue):
          while True:
              result = q.get()
              print(result)
              if result == 'end':
                  break
      
      
      if __name__ == '__main__':
          q = Queue()
          p1 = Process(target=add_task, args=(q,))
          p2 = Process(target=get_data, args=(q,))
          p1.start()
          p2.start()
      
          p1.join()
          q.put('end')
      
          # while True:
          #     result = q.get()
          #     print(result)
          #     if result == 'end':
          #         break
      
  7. 进程的数据共享

    • from datetime import datetime
      import time
      from threading import Thread, current_thread
      from random import randint
      from multiprocessing import Process, current_process, Queue
      
      # all_data = []
      
      def download(name, q: Queue):
          print(f'{name}开始下载:{datetime.now()}')
          # print(f'当前进程:{current_process()}')
          # print(f'当前线程:{current_thread()}')
          time.sleep(randint(2, 5))
          print(f'{name}下载结束:{datetime.now()}')
          # all_data.append(f'{name}的数据')
      
          # 3. 给队列添加数据
          q.put(f'{name}的数据')
          # q.get()
      
      def get_data(q: Queue):
          while True:
              result = q.get()
              print(result)
              if result == 'end':
                  break
      
      if __name__ == '__main__':
          # 1. 创建空的队列(全局变量)
          q = Queue()
      
          p1 = Process(target=download, args=('肖申克的救赎', q))
          p2 = Process(target=download, args=('霸王别姬', q))
          p3 = Process(target=download, args=('阿甘正传', q))
          p4 = Process(target=get_data, args=(q,))
          p1.start()
          p2.start()
          p3.start()
          p4.start()
      
          p1.join()
          p2.join()
          p3.join()
      
          # 添加队列结束标志
          q.put('end')
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值