总结
-
线程类子类的用法
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() t2 = DownloadThread('霸王别姬') t2.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 from datetime import datetime import time from random import randint # 一个应用程序默认有一个进程(主进程),这个进程中默认有一个线程(主线程)。 # 一个进程中可以有多个线程 # 一个应用程序可以有多个进程 # 每个进程中至少有一个线程 # Process是进程类,在需要额外的进程的时候就创建Process的对象。 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=('沉默的羔羊',)) p1.start() p2.start() p3.start() p1.join() p2.join() p3.join() print('===========下载完成=============')
-
进程中有多个线程
from datetime import datetime import time from random import randint from multiprocessing import Process, current_process from threading import Thread, current_thread 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('霸王别姬') # 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() # assigning_task()
-
线程间的通信
from datetime import datetime import time from random import randint from multiprocessing import Process, current_process from threading import Thread, current_thread # 1.多线程数据共享:同一个进程中的多线程的数据可以直接共享。 # (同一个进程中的全局变量在作用域范围内可以接受或者存储其他任何线程中的数据) # 2.如果需要在一个线程中去获取其他多个线程中的数据,就定义一个全局的可变容器,比如列表,最好是线程的队列 # 下载的一个数据 # data = None # 下载多个数据 all_datas = [] 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()}') # return f'{name}的数据' # global data # data = f'{name}的数据' all_datas.append(f'{name}的数据') if __name__ == '__main__': t1 = Thread(target=download, args=('肖生克的救赎',)) t2 = Thread(target=download, args=('霸王别姬',)) t3 = Thread(target=download, args=('阿甘正传',)) result1 = t1.start() result2 = t2.start() result3 = t3.start() t1.join() t2.join() t3.join() # print('data:', data) print(all_datas)
-
进程间的通信
from datetime import datetime import time from random import randint from multiprocessing import Process, Queue 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()}') # 3.给队列添加数据 q.put(f'{name}的数据') def get_data(q: Queue): while True: result = q.get() print(result) if result == 'end': break if __name__ == '__main__': # 1.创建空的队列(必须是全局的) q = Queue() # 2.将队列对象作为参数传给子进程 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') # 4.获取数据 # while True: # result = q.get() # print(result) # if result == 'end': # break
-
队列的使用
from datetime import datetime import time from random import randint from multiprocessing import Process, Queue from threading import Thread 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