2016-02-16 2 views
0

Я ищу способ запустить фоновый поток очереди неограниченное количество раз. Код ниже - это то, что я придумал из исследования, но меня ограничивает количество потоков, которые я создаю. В моем исследовании я не смог найти способ иметь только 1 или 2 потока, которые всегда доступны, и запускать функцию набора, когда я добавляю его в очередь.Python 2.7 threading queue, reuse threads

Цель этого примера приложения - проверить статус сайта каждые 10 секунд, если код ответа не равен 200, запустите код в функции уведомления.

Что происходит сейчас, так это то, что код работает правильно, пока я не достиг предела нитей, которые я создал, 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() 

ответ

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() 
+0

Это отлично работало для моих нужд. Мне нужно немного поиграть с этим кодом, чтобы понять, как бесконечный цикл для функции уведомления исправляет проблему. – mazpro

+0

В исходной реализации каждый поток принимал __one__ URL из очереди, обрабатывал его и затем заканчивал. Вот почему из очереди обрабатывались только сообщения «num_threads» (после того как все потоки закончились, некому было обработать URLS, которые 'make_requests' постоянно добавляли в очередь). Теперь каждый поток получает одно сообщение из очереди, обрабатывает его, но вместо того, чтобы заканчивать, он ждет (неопределенно) для очередного URL-адреса, который будет помещен в очередь, а когда новый URL-адрес находится в очереди, он обрабатывает его и скоро.... – CristiFati