多线程

import threading,time

def run():
    time.sleep(3)#停3秒
    print('哈哈哈')

for i in range(5):#串行,1个1个执行,共用时15秒
    run()

for i in range(5):
    t=threading.Thread(target=run)#实例化了一个线程;#并发,共用时3秒
    t.start()
import threading,time,requests
urls={
    'besttest':'http://www.besttest.cn',
    'nn':'http://www.nnzhp.cn',
    'dsx':'http://www.imdsx.cn',
    'cc':'http://www.cc-na.cn',
    'alin':'http://www.limlhome.cn/blog/'
}

def down_html(file_name,url):#定义一个下载函数
    res=requests.get(url).content
    open(file_name+'.html','wb').write(res)#wb代表二进制
#1、串行
# start_time=time.time()
# for k,v in urls.items():
#     down_html(k,v)
# end_time=time.time()
# runtime=end_time-start_time
# print('下载一共花了%s'%runtime)



#1、并行
start_time=time.time()
for k,v in urls.items():
    t=threading.Thread(target=down_html,args=(k,v))#多线程函数如果传参的知必须得用args
    t.start()
end_time=time.time()
runtime=end_time-start_time
print('下载一共花了%s'%runtime)  
#并行的时候用这个执行时花费时间只有0.01秒,肯定是不对的,这是因为运行的是主线程的时间,而不包括下面5个子线程的时间;
进程里面默认有一个线程,这个线程叫做主线程,主线程的作用是运行代码,下面启动的都是子线程;主线程把5个线程启动,在继续向下执行;
#串行
# start_time=time.time()
# for k,v in urls.items():
#     t=threading.Thread(target=down_html,args=(k,v))#多线程函数如果传参的知必须得用args
#     t.start()
#     t.join()#主线程等待子线程执行结束
# end_time=time.time()
# runtime=end_time-start_time
# print('下载一共花了%s'%runtime)

#等待t.join如果在循环里面等待,又变成串行了

# def run():
#     time.sleep(3)
#     print('哈哈哈')
# start_time=time.time()
# threads=[] #存放启动的5个线程
# for i in range(5):
#     t=threading.Thread(target=run)
#     t.start()
#     threads.append(t)
# for t in threads:#主线程循环等待5个子线程结束
#     t.join()
# end_time=time.time()
# runtime=end_time-start_time
# print('下载一共花了%s'%runtime)


#1、并行
start_time=time.time()
threads = []  # 存放启动的5个线程
for k,v in urls.items():
    t=threading.Thread(target=down_html,args=(k,v))#多线程函数如果传参的知必须得用args
    t.start()
    threads.append(t)
for t in threads:
    t.join()
end_time=time.time()
runtime=end_time-start_time
print('下载一共花了%s'%runtime)

 打印每个线程的用时

def down_html(file_name,url):#定义一个下载函数
    start_time=time.time()
    res=requests.get(url).content
    open(file_name+'.html','wb').write(res)#wb代表二进制
    end_time=time.time()
    runtime=end_time-start_time
    print(runtime,url)
start_time=time.time()
threads = []  # 存放启动的5个线程
for k,v in urls.items():
    t=threading.Thread(target=down_html,args=(k,v))#多线程函数如果传参的知必须得用args
    t.start()
    threads.append(t)
for t in threads:
    t.join()
end_time=time.time()
runtime=end_time-start_time
print('下载一共花了%s'%runtime)

 优化

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
    data[url]=run_time
threads=[]
start_time=time.time()
for k,v in urls.items():
    t=threading.Thread(target=down_html,args=(k,v))#多线程函数如果传参的知必须得用args
    t.start()
    threads.append(t)
for t in threads:
    t.join()
end_time=time.time()
runtime=end_time-start_time
print(data,'下载一共花了%s'%runtime)

为什么存在串行比并行快的情况:电脑CPU是几核,只能同时运行几个线程;所有的性能测试工具都不是实际意义上的并发,因为CPU处理的速度特别快;我们感觉不到

但是python的多线程只能利用1个CPU的核心;所以很多人说python的多线程不好,很鸡肋;GIL:全局解释器锁;利用多核CPU时,需要把数据放在每一个CPU的核心上,担心分一个CPU处理完的数据和原来的数据不一样;所以就设计了一个全局解释器锁的东西;保证数据不会乱;电脑CPU核数在多,也只能利用1个CPU

原文地址:https://www.cnblogs.com/ruijie/p/10727661.html