如果我们要爬取多个网站的一些数据
单线程,单进程时
只使用for循环一个个的遍历URL并读取响应,使用IPython的%%time函数统计消耗的时间。
import urllib.request
form concurrent.futures import ThreadPoolExecutor
urls=[
“https://www.codepku.com/”,
“https://www.codepku.com/informations/notice”,
“https://www.codepku.com/informations/event”,
“https://www.codepku.com/informations/offline”,
“https://www.codepku.com/informations/information”,
“https://www.codepku.com/course”,
“https://www.codepku.com/course/enlightenment”,
“https://www.codepku.com/teach”,
“http://kids.codepku.com/”,
“http://kids.codepku.com/work/list”,
“http://kids.codepku.com/hacker/tech”,
“http://kids.codepku.com/ranking/list”,
“http://kids.codepku.com/match”,
]
%%time
results=[]
for url in urls:
with urllib.request.urlopen(rul)as src:
results.append(src)
读取这些网页大概需要12秒钟。
多线程,比如4个线程,%%time下面的代码改为
with ThreadPoolExecutor(4)as executor:
results=executor.map(rullib.request.urlopen.urls)
这时从12秒变成3秒多,接近4秒了。
单进程,计算100万以内所有质数的和。
def if_prime(x):
if x<=1:
return 0
elif x<=3:
return x
elif x%2==0 or x%3==0:
return 0
i=5
while i**2<=x:
if x%i==0 or x%(i+2)==0:
return 0
i+=6
return x
%%time
answer=0
for i in range(1000000):
answer+=if_prime(i)
耗时3.48秒钟
多进程
from muItiprocessing import Pool
def if_prime(x):
if x<=1:
return 0
elif x<=3:
return x
elif x%2==0 or x%3==0:
return 0
i=5
while i**2<=x:
if x%i==0 or x%(i+2)==0:
return 0
i+=6
return x
%%time
if __name__==‘__main__’:
with Pool(2)as p:
answer=sum(p.map(if_prime.list(range(1000000))))
使用2进程,耗时1.91秒钟
在数据共享、同步方面,多进程是数据共享复杂,需要用IPC,数据是分开的,同步简单。多线程因为共享进程数据,数据共享简单,但同步复杂;在内存、CPU方面,多进程占用内存多,切换复杂,CPU利用率低。多线程占用内存少,切换简单,CPU利用率高;在创建销毁、切换方面,多进程创建销毁、切换复杂,速度慢。多线程创建销毁、切换简单,速度很快;在编程、调试方面,多进程编程和调试都简单。多线程编程和调试都复杂;可靠性方面,多进程间不会互相影响。多线程中的一个线程挂掉将导致整个进程挂掉;在分布式方面,多进程适应于多核、多机分布式。多线程适应于多核分布式。