Python当中的线程模块threading【多测师】
在Python语言中,对线程的操作使使用的是threading,下面首先通过一个案例来测试进程和线程的
访问速度,首先见测试代码:
#!/usr/bin/env python # -*-coding:utf-8 -*- import requests import threading from multiprocessing import Process import time def getApi(): r = requests.get('https://www.baidu.com/') if __name__ == '__main__': startTime=time.time() p_lists=[] for i in range(100): p=Process(target=getApi) p.start() p_lists.append(p) for i in p_lists:i.join() print('进程的测试速度为:',time.time()-startTime) t_lists=[] for i in range(100): t=threading.Thread(target=getApi) t.start() t_lists.append(t) for i in t_lists:i.join() print('线程的测试速度为:',time.time()-startTime)
见执行代码后输出的结果信息:
进程的测试速度为: 10.218018054962158 线程的测试速度为: 13.774824380874634 Process finished with exit code 0
从输出结果来来看,进程的效率更搞点,在进程中,主要使用的是threading里面的Thread类,下面还是以访问
百度为案例来说明它的应用:
#!/usr/bin/env python # -*-coding:utf-8 -*- import requests import threading from multiprocessing import Process import time def getApi(): r = requests.get('https://www.baidu.com/') print(r.status_code) class Api(threading.Thread): def run(self): getApi() if __name__ == '__main__': t_lists=[] for i in range(10): t=Api() t.start() t_lists.append(t) for i in t_lists:i.join()
在线程中它的数据是共享的,在进程中数据是隔离的,还是根据一个案例代码来看线程中的数据共享,见案例代码:
#!/usr/bin/env python # -*-coding:utf-8 -*- import threading from multiprocessing import Process n=10 def func(): global n n-=1 if __name__ == '__main__': t_lists=[] for i in range(10): t=threading.Thread(target=func) t.start() t_lists.append(t) for i in t_lists:i.join() print('n的最终结果是:',n)
最终输出的结果是0。当然某些时候也是会使用到守护进程,守护进程一直等到所有的进程执行结束后才结束,它守护
主进程和子进程,见案例代码:
#!/usr/bin/env python # -*-coding:utf-8 -*- import threading from multiprocessing import Process import time def son1(): while True: time.sleep(0.5) print('in son') t=threading.Thread(target=son1) #设置为守护线程 t.daemon=True t.start() #3秒后,守护线程结束 time.sleep(1)
因为守护进程1秒就结束,所以循环只会被执行一次。
生产者消费者的模型是警经常使用到的一种模型,当然这地方就需要使用到queue模块里面的Queue,也就是说生产者生产信息
消费者消费信息,当生产者生产的信息大于消费者,消费者一直可以消费,但是如果消费的速度大于生产者的速度,那么也就出现
消费者等待的情况,还是以一个网页的案例为例子,获取网页的数据,然后获取里面想要的信息,见实现的案例代码:
#!/usr/bin/python3 #coding:utf-8 import requests from lxml import etree import time as t import os import re from urllib import request import urllib import threading from queue import Queue class Product(threading.Thread): def __init__(self,page_queue,info_queue,*args,**kwargs): super(Product,self).__init__(*args,**kwargs) self.page_queue=page_queue self.info_queue=info_queue def run(self): while True: if self.page_queue.empty(): break url=self.page_queue.get() self.paser_page(url=url) def getHeaders(self): headers={'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'} def paser_page(self,url): '''对页面的信息进行分析''' while True: t.sleep(1) r=requests.get(url=url,headers=self.getHeaders()) if r.status_code==520: continue else: break text=r.content.decode('utf-8') html=etree.HTML(text) titles=html.xpath('//div[@class="cont"]/p//b/text()') authors=html.xpath('//p[@class="source"]//a[2]/text()') infos=list(zip(titles,authors)) #生产者生产信息 self.info_queue.put((infos)) class Consumer(threading.Thread): def __init__(self,page_queue,info_queue,*args,**kwargs): super(Consumer,self).__init__(*args,**kwargs) self.page_queue=page_queue self.info_queue=info_queue def run(self): while True: if self.page_queue.empty() and self.info_queue.empty(): break #消费者获取信息 infos=self.info_queue.get() for i in infos: print(i) def main(): #定义好页面的队列 page_queue=Queue(1000) info_queue=Queue(1000) for i in range(1,1000): url = 'https://so.gushiwen.org/shiwen/default_0AA{0}.aspx'.format(i) page_queue.put(url) for i in range(5): p=Product(page_queue=page_queue,info_queue=info_queue) p.start() for i in range(5): c=Consumer(page_queue=page_queue,info_queue=info_queue) c.start() if __name__ == '__main__': main()