线程有三种基本状态:
1、就绪状态:指线程具备运行的所有条件,逻辑上可以运行,在等待处理机会
2、运行状态:指线程占用处理机会,并正在运行
3、阻塞状态:值线程在等待一个事件(如某个信号量),逻辑上不可执行
由于GIL(全局解释器锁)的存在,python的多线程只能调用一个CPU,因此在当今多核的情况下,成为了一个缺陷。因此在执行计算密集型任务时,适合使用多进程;当执行I/O密集型任务时,适合使用多线程
from multiprocessing import Process
import time
import os
# 计算密集型任务
def work():
res = 0
for i in range(100000000):
res *= i
if __name__ == '__main__':
l = []
print(f"本机为{os.cpu_count()}核cpu机器") # 本机为12核cpu机器
start = time.time()
for i in range(4):
p = Process(target=work)
l.append(p)
p.start()
for i in l:
i.join()
end = time.time()
print("计算密集型任务,多进程耗时:%s" % (end - start))
执行结果:耗时5.4秒
本机为12核cpu机器
计算密集型任务,多进程耗时:5.387600898742676
from threading import Thread
import time
import os
# 计算密集型任务
def work():
res = 0
for i in range(100000000):
res *= i
if __name__ == '__main__':
l = []
print(f"本机为{os.cpu_count()}核cpu机器") # 本机为12核cpu机器
start = time.time()
for i in range(4):
p = Thread(target=work)
l.append(p)
p.start()
for i in l:
i.join()
end = time.time()
print("计算密集型任务,多进程耗时:%s" % (end - start))
执行结果:执行时间为16.3秒,在执行计算密集型任务,比多线程慢了近近3倍。
本机为12核cpu机器
计算密集型任务,多进程耗时:16.26915717124939
from multiprocessing import Process
import time
import os
# I/O密集型任务
def work():
time.sleep(2)
print("===>", file=open("tmp.txt", "w"))
if __name__ == '__main__':
l = []
print(f"本机为{os.cpu_count()}核cpu机器") # 本机为12核cpu机器
start = time.time()
for i in range(4):
p = Process(target=work)
l.append(p)
p.start()
for i in l:
i.join()
end = time.time()
print("计算密集型任务,多进程耗时:%s" % (end - start))
执行结果:执行耗时2.1秒
本机为12核cpu机器
计算密集型任务,多进程耗时:2.137941837310791
from threading import Thread
import time
import os
# I/O密集型任务
def work():
time.sleep(2)
print("===>", file=open("tmp.txt", "w")) # 将 ===》 写入到 tmp.txt文件
if __name__ == '__main__':
l = []
print(f"本机为{os.cpu_count()}核cpu机器") # 本机为12核cpu机器
start = time.time()
for i in range(4):
p = Thread(target=work)
l.append(p)
p.start()
for i in l:
i.join()
end = time.time()
print("计算密集型任务,多进程耗时:%s" % (end - start))
执行结果:执行I/O密集型任务,比多进程快了一些
本机为12核cpu机器
计算密集型任务,多进程耗时:2.0026445388793945
import threading
import time
def task_thread(counter):
print(f'线程名称:{threading.current_thread().name} 参数:{counter} 开始时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
num = counter
while num:
time.sleep(2)
num -= 1
print(f'线程名称:{threading.current_thread().name} 参数:{counter} 结束时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
if __name__ == '__main__':
print(f"主线程开始时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
# 实例化3个线程,传入不同的参数
t1 = threading.Thread(target=task_thread, args=(3,))
t2 = threading.Thread(target=task_thread, args=(2,))
t3 = threading.Thread(target=task_thread, args=(1,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(f"主线程结束时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
执行结果:
主线程开始时间:2021-05-19 23:57:46
线程名称:Thread-1 参数:3 开始时间:2021-05-19 23:57:46
线程名称:Thread-2 参数:2 开始时间:2021-05-19 23:57:46
线程名称:Thread-3 参数:1 开始时间:2021-05-19 23:57:46
线程名称:Thread-3 参数:1 结束时间:2021-05-19 23:57:48
线程名称:Thread-2 参数:2 结束时间:2021-05-19 23:57:50
线程名称:Thread-1 参数:3 结束时间:2021-05-19 23:57:52
主线程结束时间:2021-05-19 23:57:52
Process finished with exit code 0
import threading
import time
class Mythread(threading.Thread):
def __init__(self, counter):
super().__init__() # 调用父类的__init__()方法
self.counter = counter
def run(self):
print(f'线程名称:{threading.current_thread().name} 参数:{self.counter} 开始时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
num = self.counter
while num:
time.sleep(2)
num -= 1
print(f'线程名称:{threading.current_thread().name} 参数:{self.counter} 结束时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
if __name__ == '__main__':
print(f"主线程开始时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
# 实例化3个线程,传入不同的参数
t1 = Mythread(3)
t2 = Mythread(2)
t3 = Mythread(1)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(f"主线程结束时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
执行结果
主线程开始时间:2021-05-20 00:05:13
线程名称:Thread-1 参数:3 开始时间:2021-05-20 00:05:13
线程名称:Thread-2 参数:2 开始时间:2021-05-20 00:05:13
线程名称:Thread-3 参数:1 开始时间:2021-05-20 00:05:13
线程名称:Thread-3 参数:1 结束时间:2021-05-20 00:05:15
线程名称:Thread-2 参数:2 结束时间:2021-05-20 00:05:17
线程名称:Thread-1 参数:3 结束时间:2021-05-20 00:05:19
主线程结束时间:2021-05-20 00:05:19
Process finished with exit code 0
import threading
import time
# 定义外部函数
def out_func(counter):
print(f'线程名称:{threading.current_thread().name} 参数:{counter} 开始时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
num = counter
while num:
time.sleep(2)
num -= 1
print(f'线程名称:{threading.current_thread().name} 参数:{counter} 结束时间:{time.strftime("%Y-%m-%d %H:%M:%S")}')
class Mythread(threading.Thread):
def __init__(self, target, args):
super().__init__()
self.target = target
self.args = args
def run(self):
self.target(*self.args) # *self.args,打散args参数
if __name__ == '__main__':
print(f"主线程开始时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
# 实例化3个线程,传入不同的参数
t1 = Mythread(target=out_func, args=(3,))
t2 = Mythread(target=out_func, args=(2,))
t3 = Mythread(target=out_func, args=(1,))
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print(f"主线程结束时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
执行结果:
主线程开始时间:2021-05-20 00:13:06
线程名称:Thread-1 参数:3 开始时间:2021-05-20 00:13:06
线程名称:Thread-2 参数:2 开始时间:2021-05-20 00:13:06
线程名称:Thread-3 参数:1 开始时间:2021-05-20 00:13:06
线程名称:Thread-3 参数:1 结束时间:2021-05-20 00:13:08
线程名称:Thread-2 参数:2 结束时间:2021-05-20 00:13:10
线程名称:Thread-1 参数:3 结束时间:2021-05-20 00:13:12
主线程结束时间:2021-05-20 00:13:12
Process finished with exit code 0