Day7_多线程和多进程的使用
线程类子类的用法
1.创建线程类的子类
from threading import Thread, current_thread
import time
# 1.创建线程类的子类
class Download_Img_Thread(Thread):
# 3.如果实现子线程中的任务需要额外的数据,数据通过对象属性来提供
def __init__(self, name):
super().__init__()
self.name = name
# 2.实现run方法确定线程任务
def run(self) -> None:
print(f'开始下载{self.name}')
print(current_thread())
time.sleep(2)
print(f'{self.name}结束下载')
print(f'外面,{current_thread()}')
t1 = Download_Img_Thread('肖生克的救赎')
t1.start()
t2 = Download_Img_Thread()
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操作后面的代码只有在线程对象的任务完成后才会执行.
# =====================三个电影下载结束后才打印'电影下载结束'====================
# t1.start()
# t2.start()
# t3.start()
# t1.join()
# t2.join()
# t3.join()
# print('电影下载结束')
# ==============第一个电影下载结束后另外两个电影才能同时开始下载====================
# t1.start()
# t1.join()
# t2.start()
# t3.start()
# =============在子线程中等待三个电影下载电影结束打印'下载完成'====================
# t1.start()
# t2.start()
# t3.start()
# t4 = Thread(target=wait)
# t4.start()
# while True:
# input("请输入数据:")
多进程
-
一个应用程序默认有一个进程(主线程),这个进程中默认有一个线程(主线程)
-
一个进程中可以有多个线程
-
一个应用程序可以有多个进程
-
一个进程中至少有一个线程
from multiprocessing import Process
import time
from random import randint
from datetime import datetime
# 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('下载完成!')
进程中有多个线程
import time
from random import randint
from datetime import datetime
from threading import Thread, current_thread
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('霸王别姬')
# 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()
线程间通道
-
多个线程数据共享:同一个进程中的多线程的数据可以直接共享.
同一个进程中的全局变量在作用域范围内可以接受或者存储其他任何线程中的数据.
-
如果需要在一个线程中去获取其他多个线程的数据,就定义一个全局的可变容器,比如列表,最好是线程的队列
import time
from random import randint
from datetime import datetime
from threading import Thread, current_thread
from multiprocessing import Process, current_process
# 下载一个的数据
# 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()}')
# 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=('阿甘正传',))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(all_datas)
进程间通信
import time
from random import randint
from datetime import datetime
from threading import Thread, current_thread
from multiprocessing import Process, current_process, Queue
all_datas = []
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()}')
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')