我有一个奇怪的情况,经过大量的打击试验后无法弄明白。我使用多线程(10)来读取网址(100)并且在大多数情况下它工作正常,但在某些情况下,它会卡在最后一个线程上。我等待它看它是否返回并花了很多时间(1050秒),而其余的九个线程在25秒内返回。它显示我的代码出了问题,但无法弄明白。有任何想法吗?
注1:守护程序和非守护程序线程都会发生。
注意2:URL和线程更改的数量。我尝试了10-100个不同数量的URL和5-50个不同的线程。
注3:网址大部分时间完全不同。
import urllib2
import Queue
import threading
from goose import Goose
input_queue = Queue.Queue()
result_queue = Queue.Queue()
线程工作者:
def worker(input_queue, result_queue):
queue_full = true
while queue_full:
try:
url = input_queue.get(False)
read a url using urllib2 and goose
process it
result_queue.put(updated value)
except Queue.Empty:
queue_full = False
主要流程:
for url in urls:
input_queue.put(url)
thread_count = 5
for t in range(thread_count):
t = threading.Thread(target=worker, args= (input_queue, result_queue))
t.start()
for url in urls:
url = result_queue.get() # updates url
该进程在最后一次result_queue.get()调用时被阻止。
注意:我对我在这里做错了什么更感兴趣,万一有人可以指出这一点?因为我倾向于认为我编写了正确的代码,但显然这并不是让我疯狂的情况:)
答案 0 :(得分:1)
例如,我将URL作为数字列表
import urllib2
import Queue
import threading
#from goose import Goose
input_queue = Queue.Queue()
result_queue = Queue.Queue()
def worker(input_queue, result_queue):
while not input_queue.empty():
try:
url = input_queue.get(False)
updated_value = int(url) * 9
result_queue.put(updated_value)
except Queue.Empty:
pass
urls = [1,2,3,4,5,6,7,8,9]
for url in urls:
input_queue.put(url)
thread_count = 5
for i in range(thread_count):
t = threading.Thread(target=worker, args= (input_queue, result_queue))
t.start()
t.join()
for url in urls:
try:
url = result_queue.get()
print url
except Queue.Empty:
pass
<强>输出强>
9
18
27
36
45
54
63
72
81
答案 1 :(得分:1)
您可以使用ThreadPoolExecutor
中的concurrent.futures
。
from concurrent.futures import ThreadPoolExecutor
MAX_WORKERS = 50
def worker(url):
response = requests.get(url)
return response.content
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
results = executor.map(worker, urls)
for result in results:
print(result)