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)中
# -*- 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
似乎更符合逻辑?