Day-26 多线程和多进程
-
线程类子类的用法
-
创建线程类的子类
-
实现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()
-
-
多线程图片的下载
-
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()
-
-
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('请输入数据:')
-
-
多进程
-
一个应用程序默认有一个进程(主进程), 这个进程中默认有一个线程(主线程)
-
一个进程中可以有多个线程
-
一个应用程序可以有多个进程
-
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()
-
-
进程中的多线程
-
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()
-
-
线程的数据共享
-
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
-
-
进程的数据共享
-
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')
-