注册
登录
查看:330 | 回复:4
被波波
为什么python多线程没有加速程序的效果,求大神解答
发表于 2023/7/21 9:20:31
楼主
import  requests
import queue
import time
import logging
import threading
loghandel=logging.getLogger( totest )
fhand = logging.FileHandler( ./log/main.log ,  a )
formator = logging.Formatter(
     %(asctime)s - %(name)s - %(levelname)s - %(module)s - %(lineno)d - %(message)s ,
     %a, %d %b %Y %H:%M:%S )
fhand.setFormatter(formator)
fhand.setLevel(logging.DEBUG)
loghandel.addHandler(fhand)
loghandel.setLevel(logging.DEBUG)
def test5(threadcount):
    reqqueue = queue.Queue()
    respqueue=queue.Queue()
    for i in range(1,624):
        reqqueue.put( http://club.autohome.com.cn/bbs/forum-c-3170-{0}.html?orderby=dateline qaType=-1 .format(i))
    def downloadpage(url):
        starttime = time.time()
        startclock = time.clock()
        rsp = requests.get(url)
        endtime = time.time()
        endclock = time.clock()
        loghandel.info(rsp.url +     + str(rsp.elapsed.microseconds) +     + str(rsp.status_code) +     + str(
            endtime - starttime)+   + str(endclock - startclock))
        respqueue.put(rsp)
    while reqqueue.qsize()!=0:
        threadpool=[]
        for i in range(1, threadcount):
            try:
                page = reqqueue.get(block=False)
                t = threading.Thread(target=downloadpage(page))
                threadpool.append(t)
            except queue.Empty as e:
                loghandel.error( the pagequeue is empty )
                break
        for t in threadpool:
            t.start()
        for t in threadpool:
            t.join()
        threadpool.clear()
    return respqueue
if __name__ ==  __main__ :
    for i in [2, 6, 11, 31, 51]:
        starttime = time.time()
        startclock = time.clock()
        test5(i)
        endtime = time.time()
        endclock = time.clock()
        print(str(i - 1), endtime - starttime, endclock - startclock)


被波波
发表于 2023/7/21 9:25:16
沙发

image.png

天行者
发表于 2023/7/21 9:26:00
板凳

t = threading.Thread(target=downloadpage(page)) 这句话有误,

你这实际上是主线程调用downloadpage(page),然后把返回值赋值给target,

你可以在downloadpage方法种加入print threading.current_thread().getName()语句看看执行的线程就知道了,

应该写成: t = threading.Thread(target=downloadpage,args=(page,))

因此你代码执行的效果就是main线程串行执行,没有其他线程并发。

其次,你这个线程池是不对的,你这样写每次都会创建一个新的线程对象去执行downloadpage方法,达不到线程复用的目的……


兰陵王
发表于 2023/7/21 9:28:23
4楼

分析的很透彻


被波波
发表于 2023/7/21 9:29:21
5楼

感谢指点。

我又改进了一下,downloadpage这个方法不传参数了,在这个方法里面加了一个循环,如果队列中仍有url,就取出来并访问。

这样就不用每次创建对象了。抓取速度简直飞一般的感觉。

不过这个也就是取个巧,还不是线程池。我百度过,python3好像是没有现成的线程池方面的包的,不知道是不是这样。


立即注册站大爷用户,免费试用全部产品
立即注册站大爷用户,免费试用全部产品