线程是一个基本的CPU执行单元。它必须依托于进程存活。一个线程是一个execution context(执行上下文),即一个CPU执行时所需要的一串指令。每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。
import os
import time
import threading
from concurrent.futures import ThreadPoolExecutor
def sing():
print("A线程", threading.current_thread()) # 获取当前线程的线程对象 threading.current_thread()
for i in range(3):
print("a唱歌》》》")
time.sleep(0.5)
def sing2(num):
print("B线程", threading.current_thread())
for i in range(num):
print("b唱歌》》》")
time.sleep(0.5)
def sing3(num):
print("C线程",threading.current_thread())
for i in range(num):
print("c唱歌》》》")
time.sleep(0.5)
if __name__ == '__main__':
# 线程是程序执行的最小单位,同一进程内的线程共享所有的公共资源
# 线程传递参数方式与进程类似,可以使用元组和字典
# 创建线程对象
sing1_thread = threading.Thread(target=sing)
sing2_thread = threading.Thread(target=sing2, args=(3,))
# 默认情况下主进程会等待所有的子进程执行结束再结束
# 1.设置守护主进程,主进程退出后子进程直接销毁,不再执行子进程中的代码
# sing1_thread.daemon = True
# sing2_thread.daemon = True
# 2. 也可以通过创建线程对象的时候通过daemon关键字设置实现
# sing1_thread = Thread(target=sing2, args=(3,), daemon=True)
# 3. 通过setDaemon设置(在start之前)
# sing1_thread.setDaemon(True)
# 启动线程对象
sing1_thread.start()
sing2_thread.start()
# # 等待结束(结束之后才会执行后面的语句)
# sing1_thread.join()
# sing2_thread.join()
print("主线程结束了")
多线程实现拷贝器
import os
import time
import threading
from concurrent.futures import ThreadPoolExecutor
def copy_file(file_name, source_dir, dest_dir):
# 1.源文件路径拼接
source_file = source_dir + '/' + file_name
# 2.源文件路径拼接
dest_file = dest_dir + '/' + file_name
# 3.打开目标文件和源文件
with open(source_file, 'rb') as source_file:
with open(dest_file, 'wb') as dest_file:
# 4.循环遍历读取数据和写入数据
while True:
file_data = source_file.read()
if file_data:
dest_file.read(file_data)
else:
break
if __name__ == '__main__':
# 1.设置目标文件夹和源文件夹
source_dir = "D:/python/多进程和多线程/test"
dest_dir = "D:/python/多进程和多线程/dest"
# 2. 创建文件夹
try:
os.mkdir(dest_dir)
except:
print("目标文件夹已经存在!")
# 3. 读取目标文件名
file_list = os.listdir(source_dir)
# 4.遍历列表得到文件名
for file_name in file_list:
# 5.创建子线程子线程实现拷贝
sub_thread = threading.Thread(target=copy_file, args= (file_name, source_dir, dest_dir, ))
sub_thread.start()
"""
使用线程池的好处:
1. 提升性能,因为减去了大量新建、终止线程的开销,重用了线程资源
2. 适用场景,适合处理大量请求或需要大量线程完成任务、但实际任务处理时间较短
3. 防御功能,能有效避免因为创建线程过多,而导致系统负荷过大相应变慢等问题
4. 代码优势,使用线程池的语法比自己新建执行线程更加简洁
"""
# file_listnew = []
# for file_name in file_list:
# file_listnew.append((file_name, source_dir, dest_dir))
# # print(zip(file_name, source_dir, dest_dir))
# # print(file_listnew)
# with ThreadPoolExecutor() as pool:
# results = pool.map(copy_file, file_listnew)
# for result in results:
# print(result)