Python中的多线程:陷入最后的线程

时间:2017-08-22 15:48:06

标签: python python-2.7 python-multiprocessing python-multithreading

我有一个奇怪的情况,经过大量的打击试验后无法弄明白。我使用多线程(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()调用时被阻止。

注意:我对我在这里做错了什么更感兴趣,万一有人可以指出这一点?因为我倾向于认为我编写了正确的代码,但显然这并不是让我疯狂的情况:)

2 个答案:

答案 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)