Python 线停得太快了

Python 线停得太快了,python,multithreading,python-2.7,parallel-processing,Python,Multithreading,Python 2.7,Parallel Processing,我正在尝试制作一个脚本,它有两个并行的功能: 一个线程:请求服务器并将响应附加到池中的responses变量(list)中 第二个线程:处理响应列表中的响应 它似乎有效,但在所有产品加工之前就停止了。例如,完成了70个产品,但剩下30个 # -*- coding: utf-8 -*- from datetime import datetime from multiprocessing.pool import ThreadPool as Pool from threading import Th

我正在尝试制作一个脚本,它有两个并行的功能:

  • 一个线程:请求服务器并将响应附加到
    池中的responses变量(list)中
  • 第二个线程:处理响应列表中的响应
  • 它似乎有效,但在所有产品加工之前就停止了。例如,完成了70个产品,但剩下30个

    # -*- coding: utf-8 -*-
    
    from datetime import datetime
    from multiprocessing.pool import ThreadPool as Pool
    from threading import Thread
    import requests
    
    RESPONSES = []
    POOL_IS_ALIVE = True
    
    with open('products.txt') as f:
        LINES = f.readlines()[:100]
    
    def post_request(url):
        html = requests.get(url).content
        RESPONSES.append(html)
    
    
    def parse_product(html, url):
        # long code which returns instance of class product
    
    def start_requesting(): # Creates a pool with 100 workers
        pool = Pool(100)
    
        for n,line in enumerate(LINES):
            pool.apply_async(post_request, args=(line[:-1],))
    
        pool.close()
        pool.join()
    
    t1 = Thread(target=start_requesting)
    
    def process_responses():
        i=0
        db = db_manager.db_manager()
    
        while True:
            try:
                response = RESPONSES.pop()
            except IndexError:
                continue
    
            product = parse_product(response,'url')
            db.insert_product(product)
    
            if not t1.is_alive():
                print 'IS_ALIVE NOT'
                break
    
    
    t2 = Thread(target=process_responses)
    
    now = datetime.now()
    
    t1.start()
    t2.start()
    t2.join() # MAYBE HERE IS THE PROBLEM
    t1.join()
    
    
    print now-datetime.now()
    

    问题出在哪里?

    首先,您的代码中有一些错误:

    if not t.is_alive():
        print 'IS_ALIVE NOT'
        break
    
    根本没有变量“t”,难道你没有遇到类似“
    NameError:name't'未定义”这样的错误吗

    第二,只需打印程序的步骤,看看哪个步骤超出了预期。或者您可以使用python调试器

    第三,

    RESPONSES = []
    

    RESPONSE
    是线程安全的,但正如@mguijarr提到的,使用更好。

    首先,代码中有一些错误:

    if not t.is_alive():
        print 'IS_ALIVE NOT'
        break
    
    根本没有变量“t”,难道你没有遇到类似“
    NameError:name't'未定义”这样的错误吗

    第二,只需打印程序的步骤,看看哪个步骤超出了预期。或者您可以使用python调试器

    第三,

    RESPONSES = []
    

    RESPONSE
    是线程安全的,但正如@mguijarr提到的,使用更好。

    RESPONSE
    是一个列表,在CPython中,附加到列表是线程安全的,因为它是一个原子操作(多亏了GIL),从列表中获取一个项目也是安全的,例如
    RESPONSE[i]
    。依靠原子性是一个危险的游戏,但有时它会很有用。@mguijarr和monklof:那么什么是更好的呢?我应该使用队列吗?我使用纯Python 2.7,而不是CPython。ThanksCPython是Python的C实现,因此它对应于Python2.7或3.x。。。我对原子操作的解释在您的情况下是有效的-您的代码在线程安全方面对我来说似乎还可以,但是
    队列
    更好,因为它被设计为以互斥量为代价在线程之间共享数据。
    响应
    是一个列表,在CPython中,添加到列表是线程安全的,因为它是一种原子操作(多亏了GIL),只从列表中获取项目也是安全的,例如
    响应[i]
    。依靠原子性是一个危险的游戏,但有时它会很有用。@mguijarr和monklof:那么什么是更好的呢?我应该使用队列吗?我使用纯Python 2.7,而不是CPython。ThanksCPython是Python的C实现,因此它对应于Python2.7或3.x。。。我对原子操作的解释在您的情况下是有效的-您的代码在线程安全方面对我来说似乎还可以,但是
    队列
    更好,因为它被设计为以互斥量为代价在线程之间共享数据。为什么您要先加入
    t2
    ?等待
    t1
    完成,然后等待
    t2
    ,似乎更符合逻辑?为什么你要先加入
    t2
    ?等待
    t1
    完成,然后等待
    t2
    似乎更符合逻辑?