python学习(三十一)线程&多线程&线程等待

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)

可以发现这段代码跟上面比起来,就多了两行,循环等待子线程执行完的过程。这个时候统计的才是线程运行的所有时间。

猜你喜欢

转载自www.cnblogs.com/emilyliu/p/9098133.html
今日推荐