import threading
import logging
import datetime
import multiprocessing
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
FORMAT = "%(thread)d %(message)s"
logging.basicConfig(format=FORMAT,level = logging.INFO)
start = datetime.datetime.now()
def calc(): #计算密集型 CPU密集型
sum = 0
for i in range(200000000):
sum += 1
logging.info('finished') #打印IO操作
if __name__ == '__main__': # 多进程池
# executor = ThreadPoolExecutor(4) # 多线程版本,多线程执行器 with上下文
executor = ProcessPoolExecutor(4) # 多进程
#GIL
task = []
# pool = multiprocessing.Pool(4)
with executor: # 上下文清理游泳池的功能 join
for i in range(4):
future = executor.submit(calc)
print('\n')
delta = (datetime.datetime.now() - start).total_seconds()
logging.info(delta)
#串行34-40s左右 墙上的时间
# 多线程 多线程上下文切换应该多一点点耗时,对于CPU密集代码来说,Python的多下称由于GIL所以没有任何优势
# 多进程10s左右,要大于34/4.
# 进程池实现4个进程 26s
上下文管理,在退出with时,本质还是调用executor的shutdown(wait = True),就是一直阻塞到所有运行的任务完成。
这个高级库提供的执行器,提供了异步使用多进程、多线程的方式,还提供了池,非常方便,推荐使用。
作业:
使用多线程在屏幕上分不同颜色交替打印1~100的数字
# **作业:**
# 使用多线程在屏幕上分不同颜色交替打印1~100的数字
import threading
import queue
import time
import random
nums = queue.Queue()
def gendata(q:queue.Queue):
num = 1
while True:
num += 1
q.put(num)
time.sleep(1)
def color_printer(q:queue.Queue,frontcolor = 30):
head = '\x1b[{}m'.format(31)
tail = '\x1b[m'
while True:
data = q.get()
print(data)
output = "{}\t{} num={}{}".format(
threading.current_thread().ident,
head,
data,
tail
)
print(output)
# 消费者
for i in range(2):
t = threading.Thread(
target=color_printer,name = 'printer-{}'.format(i+1),
args = (nums,random.randint(30,37))
)
t.start()
# 生产者
threading.Thread(target=gendata,name='gen',args=(nums,)).start()