Python 2.7线程队列,重用线程

时间:2016-02-16 20:55:13

标签: python multithreading queue

我正在寻找一种方法让后台线程队列运行无限次。下面的代码是我从研究中得出的代码,但我受限于我创建的线程数量。 根据我的研究,我无法找到一种方法,只有1或2个线程始终可用,并在我将其添加到队列时运行set函数。

此示例应用的目标是每10秒检查一次站点的状态,如果响应代码不是200,则在notify函数中运行代码。

现在发生的是代码正常工作,直到我达到我创建的线程的限制,在这种情况下为5。主while循环保持正常工作,但是当出现故障时需要执行的代码因没有更多线程而停止。

import urllib2, time
from threading import Thread
from Queue import Queue

# Set up global variables
num_threads = 5
queue = Queue()
urlList = [
    "http://google.com",
    "http://googleeeeeee1111.com"
]


def notify(i, q):
    print "Thread %s: started" % i
    url = q.get()
    print "Thread %s: notification sent for site: %s" % (i, url)
    q.task_done()


def make_requests():
    while True:
        for url in urlList:
            try:
                request = urllib2.urlopen(url)
                responseCode = request.getcode()

                # If the response code was 200, do something
                if responseCode == 200:
                    print "URL: %s  -  Success %d" % (url, responseCode)
                else:
                    print "Bad response code for %s  -  %d " % (url, responseCode)
                    queue.put(url)

            except Exception, e:
                print "ERROR MAKING REQUEST TO %s - %s" % (url, e)
                queue.put(url)
        time.sleep(10)  # wait 10 seconds and start again


if __name__ == '__main__':
    # Set up some threads to fetch the enclosures
    for i in range(num_threads):
        worker = Thread(target=notify, args=(i, queue, ))
        worker.setDaemon(True)
        worker.start()

    make_requests()

1 个答案:

答案 0 :(得分:0)

在开始之前是Python's GIL的文档以及它如何影响线程。

我不确定这是否是您正在寻找的,但您可以将notify包装成一个永无止境的循环。我修改了你的代码,以便像这样做,+一些与功能没有太大关系的小修正:

import urllib2, time
from threading import Thread
from Queue import Queue

# Set up global variables
num_threads = 3 #you can set it to any number of threads (although 1 would be enough)

queue = Queue()
url_list = [
    "http://google.com",
    "http://googleeeeeee1111.com"
]


def notify(i, q):
    url = q.get()
    print "Thread %d: notification sent for site: %s" % (i, url)
    q.task_done()


def thread_func(i, q):
    print "Thread %d: started" % i
    while True:
        notify(i, q)
    print "Thread %d: ending" % i

def make_requests():
    while True:
        for url in url_list:
            try:
                request = urllib2.urlopen(url)
                response_code = request.getcode()

                # If the response code was 200, do something
                if response_code == 200:
                    print "URL: %s  -  Success %d" % (url, response_code)
                else:
                    print "Bad response code for %s  -  %d " % (url, response_code)
                    queue.put(url)

            except Exception as e:
                print "ERROR MAKING REQUEST TO %s - %s" % (url, e)
                queue.put(url)
        time.sleep(10)  # wait 10 seconds and start again


if __name__ == "__main__":
    # Set up some threads to fetch the enclosures
    for i in xrange(num_threads):
        worker = Thread(target=thread_func, args=(i, queue))
        worker.setDaemon(True)
        worker.start()

    make_requests()