开始使用Pyton的多进程,多线程。
一、多线程,多线程的概念
多线程、多进程 1、线程是程序里面最小的执行单元。 2、进程是资源的集合。 线程是包含在一个进程里面的, 一个进程可以有多个线程。 一个进程里面默认有一个线程。 主线程 默认有个主线程 子线程: 主线程启动子线程
多进程 多用于处理CPU密集型任务 多线程 多用于IO密集型任务 Input Ouput
二、多线程
1、多线程示例1, 多线程时没有计算总共花了多少时间
import threading,timedef run(): time.sleep(3) #干活需要3秒 print('哈哈哈')for i in range(5): #串行,总共需要15秒 run()for i in range(5): t = threading.Thread(target=run) #实例了一个线程 t.start()#多线程,就是N个线程一起干活
2、多线程示例2,显示如何计算多线程时,总共的时间消耗
urls = { 'baidu':'http://www.baidu.com', 'niu':'http://www.nnzhp.cn', 'dsx':'http://www.imdsx.cn', 'cc':'http://www.cc-na.cn'}import requests,timeimport threading,timedata = {} #保存各个线程执行的时间结果def down_html(file_name, url): start_time = time.time() res = requests.get(url).content open(file_name+'.html', 'wb').write(res) end_time = time.time() run_time = end_time-start_time #计算每个线程时间 # print(end_time-start_time, url) data[url] = run_time#1、串行#统计一下时间start_time = time.time()for key, value in urls.items(): down_html(key, value)end_time = time.time()run_time = end_time - start_timeprint('下载总共花的时间', run_time)#下载总共花的时间 37.91216850280762#2、并行threads = []start_time = time.time()for key,value in urls.items(): #多线程的函数如果要传参的话,必须得调用atgs t = threading.Thread(target=down_html, args=(key,value)) t.start() threads.append(t)for t in threads: #让主线程等待所有子线程结束 t.join()#6个线程#进程里面默认有一个线程,这个线程叫主线程end_time = time.time()run_time = end_time - start_timeprint('下载总共花的时间', run_time)print(data)
3、线程总结
1、如果这个函数里面有返回值的话,怎么获取呢? 子线程运行的函数,如果里面有返回值的话,是不能获取到的 只能在外面定义一个list或者字典来存每次处理的结果。 电脑CPU有几核,那么只能同时运行几个线程。 但是呢,python的多线程,只能利用一个CPU的核心。 GIL 全局解释器锁。
三、线程锁
锁就是,在多个线程同时修改一个数据的时候,可能会把数据覆盖,在python2里面需要加锁。python3里面不加锁也无所谓,默认会自动帮你加锁。
1、线程锁示例用法
import threading,timenum = 1lock = threading.Lock() #申请一把锁def run(): time.sleep(1) global num lock.acquire() #加锁 num += 1 lock.release() #解锁ts = []for i in range(50): t = threading.Thread(target=run) t.start() ts.append(t)[t.join() for t in ts] #列表生成式 #主线程等待子线程结束print(num)
四、守护线程
#守护线程#只要主线程结束,那么子线程立即结束,不管子线程有没有运行完成
1、守护线程示例用法
import threading,timedef run(): time.sleep(3) print('哈哈哈')for i in range(50): t = threading.Thread(target=run) t.setDaemon(True) #把子线程设置为守护线程,只要主线程退出了,子线程就全退出了 t.start()print('Done, 运行完成.') #主线程运行到此,就退出了,子线程都没有运行结束,这就是守护线程。
五、线程等待
1、就是主线程等待子线程运行完成后才退出主程序
2、线程等待示例
import threading,timedef run(): time.sleep(3) #干活需要3秒 print('哈哈哈')start_time = time.time()threads = []for i in range(5): t = threading.Thread(target=run) t.start() threads.append(t) # t.join() #主线程等待子线程执行结束print(threads)for t in threads: #主线程循环等待5个子线程执行结束 t.join()#循环等待end_time = time.time()print('run_time: ', end_time-start_time)
六、多进程
1、多进程包含多线程示例
import multiprocessing,threadingdef my(): print('哈哈哈')def run(num): for i in range(num): t = threading.Thread(target=my) #进程里的多线程 t.start() # print('哈哈哈哈')if __name__== '__main__': for p in range(5): p = multiprocessing.Process(target=run,args=(6,)) #启动一个进程,只有一个参数的时候,要加一个, p.start() #多进程的启动方式,需要在__name__下才能启动#进程5个 #每个进程6个线程