一个 多线程爬视频的 py 脚本,我想看下总的执行时间,求大佬帮忙看看???
# -*- coding: utf-8 -*-
# @Author : 徐燚敏
# @File : movie_multiple.py
# @Project: python_spider
# @CreateTime : 2020-06-22 10
# encoding utf-8
import requests
from queue import Queue
import threading
import time
start_total_time = 0
end_total_time = 0
# 创建线程 生产者负责获取 URL,并且解析 URL
class Procuder(threading.Thread):
    def __init__(self, num_queue, ts_queue, *args, **kwargs):
        super(Procuder, self).__init__(*args, **kwargs)
        self.num_queue = num_queue
        self.ts_queue = ts_queue
    def run(self):
        while True:
            if self.num_queue.empty():
                # 如果队列为空就,线程执行完成,跳出死循环,结束 run
                print("Procuder 队列为空")
                break
            url = self.num_queue.get()
            self.download_ts(url)
    def download_ts(self, url):
        r = requests.get(url)
        ret = r.content
        # 倒数 8 位,取到文件名
        filename = url[-8:]
        self.ts_queue.put((ret, filename))
# 创建线程 消费者 负责下载
class Consumer(threading.Thread):
    def __init__(self, num_queue, ts_queue, *args, **kwargs):
        super(Consumer, self).__init__(*args, **kwargs)
        self.num_queue = num_queue
        self.ts_queue = ts_queue
    def run(self):
        while True:
            if self.ts_queue.empty() and self.num_queue.empty():
                # 如果队列为空就,线程执行完成,跳出死循环,结束 run
                print("Consumer 队列为空")
                end_total_time = time.time()
                break
            start_time = time.time()
            ret, filename = self.ts_queue.get()
            # 将 ts 文件保存到文件夹里
            with open('./mp4/{}'.format(filename), 'wb') as f:
                f.write(ret)
            end_time = time.time()
            print('{}下载完成!,耗时:{}'.format(filename,end_time - start_time) )
def main():
    # 定义线程
    num_queue = Queue(500)
    ts_queue = Queue(500)
    # 先自定义好总共爬取的数量
    # for i in range(470):
    for i in range(30):
        url = " https://us8.wl-cdn.com/hls/20200619/e1c5cc36967e6dac688b5e9c4006a567/film_" + '{0:05d}'.format(i) + ".ts"
        num_queue.put(url)
    # time.sleep(1)
    # 定义生产者
    for x in range(5):
        print("Procuder")
        t = Procuder(num_queue, ts_queue)
        t.start()
    # 定义消费者
    for x in range(5):
        print("Consumer")
        t = Consumer(num_queue, ts_queue)
        t.start()
if __name__ == '__main__':
    start_total_time = time.time()
    lock = threading.RLock()
    # 加锁
    lock.acquire()
    try:
        main()
    finally:
        # 修改完成,释放锁
        lock.release()
        print("完成下载,总耗时{}".format(end_total_time - start_total_time))
        
        
|  |      1Aliencn      2020-06-22 15:21:08 +08:00 调用 main 函数前后取时间戳,算差值不就行了 | 
|  |      2johnsona      2020-06-22 15:30:48 +08:00 主线程等待子线程执行完再退出,守护线程 | 
|  |      3marquina      2020-06-22 15:31:11 +08:00 via Android 弄个字典,把每个线程的耗时放进去,完事后加起来 | 
|  |      4lithbitren      2020-06-22 16:19:48 +08:00 不明白难点在哪,希望知道总时间就直接测 main 的执行时间,需要知道各个线程的时间,就在重载的 run 函数首尾加上计时就行了,然后存字典存数组都可以直接存。io 密集的无所谓,如果 cpu 密集的最好给 run 函数传入一个进入线程的时间参数,不然有时候可能一开程就被挂起了,导致时间测量不太准确。 不过这个循环也有点迷,如果判断 queue 不为空,判断完以后如果其他线程先把队列消费空了,那 get 方法就阻塞了啊。 对于这种固定数量的任务,既然都用 requests 了,那直接上 grequests 就完事了,最多重写一下里面的方法加个成功的回调(原生库里面只有失败回调)。 | 
|  |      5lithbitren      2020-06-22 16:33:00 +08:00 requests 的 asyncio 版 requests-async 也可以,或者是 httpx 也行,不过要配好官方协程,最好把 py 的版本弄新一点,不然有时候可能会出现莫名其妙的 bug 。 | 
|  |      6p1094358629 OP @marquina 并行的哦,总和当然不对 | 
|  |      7p1094358629 OP @Aliencn 不对 | 
|  |      8p1094358629 OP @lithbitren 运行就直接 print 总时间了. | 
|  |      9jugelizi      2020-06-22 20:18:25 +08:00 via Android 直接 print 最后一行就是结束时间 哈哈哈 | 
|  |      10marquina      2020-06-22 20:36:21 +08:00 @p1094358629 三个线程,线程 1 执行 3 秒,线程 2 执行 5 秒,线程 3 执行 4 秒,主线程等待三个线程结束。无非就两个执行时间,sum(3, 5, 4)、max(3, 5, 4)。先搞清楚你要的是哪个执行时间吧。 | 
|  |      11momocraft      2020-06-22 21:01:22 +08:00 什么叫执行时间  实际在 cpu 跑的时间? 任务存在的时间? | 
|  |      12p1094358629 OP | 
|  |      13nanfangzai      2020-06-29 19:57:12 +08:00 python 的多线程可以尝试下这个, 非常好用 from concurrent.futures import ThreadPoolExecutor |