1、多线程
多线程,就是N个人一起在干活
1)线程是程序里面最小的执行单元
2)进程是资源的集合
线程是包含在一个进程里面的,一个进程可以有多个线程;一个进程里面默认有一个主线程
2、串行与并行(1)
import time def run(): time.sleep(3) #干活需要3s print('哈哈哈') for i in range(5): #串行 run()
上面这段代码,循环5次,每次耗时3秒钟,总共要执行15秒才能执行完
而多线程并行处理,会缩短执行时间
import threading,time def run(): time.sleep(3) #干活需要3s print('哈哈哈') for i in range(5): #并行 t=threading.Thread(target=run)#实例化了一个线程 t.start()
在3秒后,5次循环已经执行结束了
3、串行与并行(2)
从网站获取内容并写到本地的HTML里面
1)串行
import requests urls = { 'besttest':'http://www.besttest.cn', 'niuniu':'http://xxx', 'dsx':'http://xxx', 'cc':'http://xxx', } data={} def down_html(file_name,url): start_time=time.time() res=requests.get(url).content #获取url的内容 open(file_name+'.html','wb').write(res) #把URL的内容写到xx.html里面 end_time=time.time() run_time=end_time-start_time #写内容的运行时间 data[url]=run_time #把url和执行时间写到字典里 print(data) start_time = time.time() for k,v in urls.items(): down_html(k,v) end_time=time.time() run_time=end_time-start_time print('下载总共花了xxx时间',run_time)
down_html函数作用是获取url内容并写到到指定文件里面,因为有好几个url地址,通过循环调用该函数,把每个url地址都读取并写入指定文件,并统计总共用的时间
2)并行(主线程不等待运行时间)
import threading,time urls = { 'besttest':'http://www.besttest.cn', 'niuniu':'http://xxxx', 'dsx':'http://xxxx', 'cc':'http://xxxx', } import requests data={} def down_html(file_name,url): start_time=time.time() res=requests.get(url).content #获取url的内容 open(file_name+'.html','wb').write(res) #把URL的内容写到xx.html里面 end_time=time.time() run_time=end_time-start_time #写内容的运行时间 data[url]=run_time #把url和执行时间写到字典里 print(data) threads=[] start_time = time.time() #5次 for k,v in urls.items(): t=threading.Thread(target=down_html,args=(k,v)) #args用来传参 t.start() threads.append(t) end_time=time.time() run_time=end_time-start_time #这个时间只是主线程的运行时间,主线程只是做引导作用,当子线程开始运行的时候,主线程可能已经去干别的了 print('下载总共花了xxx时间',run_time)
运行可以知道,这个总时间很短,其实这并不是这个程序完全执行的时间,只是主线程的运行时间主线程启动子线程开始执行后,主线程可能就去干别的了,以上只能记录主线程运行时间。
4、多线程等待
上面提到,主线程在启动子线程后可能就去干别的了,没有等待子线程执行,现在就来说下主线程等待子线程执行
先说一个简单的不等待的例子:
import threading,time def run(): time.sleep(3) print('hahh') start_time=time.time() threads=[] #存放启动的5个线程 for i in range(5): #主线程启动其它线程,这段代码其实主要是把5个线程启动,并不是要等子线程要把活干完 t=threading.Thread(target=run) t.start() threads.append(t) print('threads',threads) end_time=time.time() print('run_time..',end_time-start_time)
输出结果会发现run_time.. 0.0009999275207519531 只有很少的时间,说明并不是线程执行完的时候,而是主线程执行的时间。主线程在启动其他线程开始执行后,就可以去做别的事情,不必一直等待子线程的执行。所以这个执行时间并不是子线程执行完的时间。
那么怎么统计子线程的执行时间呢,那就要主线程在启动子线程开始运行后,等待每个子线程运行结束,都结束后,计算时间。
import threading,time def run(): time.sleep(3) print('hahh') start_time=time.time() threads=[] #存放启动的5个线程 for i in range(5): #主线程启动其它线程,这段代码其实主要是把5个线程启动,并不是要等子线程要把活干完 t=threading.Thread(target=run) t.start() threads.append(t) print('threads',threads) for t in threads: #该循环才是主线程等待每个子线程把活干完 t.join()#循环等待 end_time=time.time() print('run_time..',end_time-start_time)
可以发现这段代码跟上面比起来,就多了两行,循环等待子线程执行完的过程。这个时候统计的才是线程运行的所有时间。