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()

 

posted @ 2020-05-31 20:56  多测师_树哥  阅读(259)  评论(0编辑  收藏  举报