Моя первая мысль была, что вы получите ошибки из-за перегрузки на DNS - возможно, ваш распознаватель просто не позволяет вам делать больше, чем определенное количество запросов на время.
Кроме того, я заметил некоторые проблемы:
Вы забыли правильно назначить site
в цикле while
- который, вероятно, лучше заменить итерацией в for
цикл по очереди, или что-то. В вашей версии вы используете переменную site
из пространства имен уровня модуля, что может привести к тому, что запросы будут выполняться дважды, а другие пропущены.
В этом месте у вас есть контроль над тем, что в очереди все еще есть записи или их ждет. Если оба нет, вы можете выйти из своей нити.
По соображениям безопасности, вы бы лучше сделать
def mexec(befehl, args=None):
cur = conn.cursor()
cur.execute(befehl, args)
для того, чтобы сделать потом
mexec("UPDATE sites2block SET ip=%s, updated='yes'", result) #puts site in mysqldb
Для того, чтобы остаться совместимым с будущими протоколами, вы должны использовать socket.getaddrinfo()
вместо socket.gethostbyname_ex(site)
. Там вы получаете все IP-адреса, которые вы хотите (сначала вы можете ограничить IPv4, но проще переключиться на IPv6) и, возможно, поместить их в базу данных.
Для очереди, примеры кода может быть
def queue_iterator(q):
"""Iterate over the contents of a queue. Waits for new elements as long as the queue is still filling."""
while True:
try:
item = q.get(block=q.is_filling, timeout=.1)
yield item
q.task_done() # indicate that task is done.
except Empty:
# If q is still filling, continue.
# If q is empty and not filling any longer, return.
if not q.is_filling: return
def getips(i, q):
for site in queue_iterator(q):
#--resolve IP--
try:
result = socket.gethostbyname_ex(site)
print(result)
mexec("UPDATE sites2block SET ip=%s, updated='yes'", result) #puts site in mysqldb
except (socket.gaierror):
print("no ip")
mexec("UPDATE sites2block SET ip='no ip', updated='yes',")
# Indicate it is filling.
q.is_filling = True
#Spawn thread pool
for i in range(num_threads):
worker = Thread(target=getips, args=(i, queue))
worker.setDaemon(True)
worker.start()
#Place work in queue
for site in websites:
queue.put(site)
queue.is_filling = False # we are done filling, if q becomes empty, we are done.
#Wait until worker threads are done to exit
queue.join()
должен сделать трюк.
Еще одна проблема заключается в параллельной вставке в MySQL. Вам разрешено выполнять только один запрос MySQL за раз. Таким образом, вы можете либо защитить доступ через threading.Lock()
, либо RLock()
, либо вы можете отправить ответы в другую очередь, которая обрабатывается другим потоком, который может даже связывать их.
Какие ошибки вы получаете? –
sry, забыл принять! Я не получаю конкретных ошибок, сценарий работает и в какой-то момент просто зависает, не показывая никаких конкретных ошибок. Затем я должен убить оболочку. – user670186
Пример неполный - что такое 'mexec '? –