Как использовать поток для следующего объекта, который еще не использовался?

Philip Jay Fry спросил: 13 июня 2018 в 11:06 в: python

Возможно, я попытаюсь использовать threading для чего-то, чего я не должен был бы, если да, пожалуйста, позвольте я знаю.

Я сделал небольшой пример моего кода, поэтому проще понять, что мне нужно.

У меня есть входные IP-адреса пользователей, затем я пинг IP-адреса, которые они ввели. Я хотел бы выполнить ping x количество IP-адресов за раз, в этом примере его 4.

Проблема в том, что каждый поток обрабатывает все 4 IP-адреса. Я бы хотел, чтобы 1 поток был ping IP 1, затем другой для ping IP 2, а затем, если поток 1 поймал с IP 1, он переместится к следующему доступному IP-адресу (так что если поток 2 взял IP 3, то поток 1 подхватит IP4).

Таким образом, я могу выполнить ping все IP-адреса за ~ 2 секунды, а не ~ 4 секунды.

Сообщите мне, если вам нужно больше деталей.

pre>

Выход:

import threading
#prints out "pinging IP" for each IP in ip_list
def _ping(ip_list):
    for objects in ip_list:
        print ("Pinging ip: " + objects)ip_list = []#ask user for IP address, appends to ip_list
for x in range (0,4):
    ip = str(input("please enter ip: "))
    ip_list.append(ip)#calls function _ping with threading.
if __name__ == '__main__':
    numOfThreads = 2
    threadList = []
    for i in range (numOfThreads):
        t = threading.Thread(target=_ping, args=(ip_list[0:4],))
        t.start()
        threadList.append(t)

2 ответа

Есть решение
bnaecker ответил: 13 июня 2018 в 01:05

Очередь - хорошая структура данных, которая поможет решить эту проблему. Очереди представляют собой списки "первый-в-первом" (FIFO), что означает, что элементы удаляются из него в том порядке, в котором они помещаются в него. Модуль queue в стандартной библиотеке Python реализует потокобезопасную очередь, именно то, что вам нужно.

Вы можете включить основной поток в IP-адрес всех IP-адресов, затем каждый поток будет удалите из него. Это приведет к удалению элемента, так что потоки получат IP-адрес, если он еще не обработан. Это потребует лишь незначительной модификации вашего существующего кода.

Самое важное изменение заключается в том, что вам нужно каким-то образом отключить потоки, когда больше нет элементов для обработки. Наиболее распространенный способ сделать это - добавить "дозорный", некоторый объект, который уведомляет поток о завершении работы. None - это общий выбор, так же как и пустая строка.

import threading
import queuedef _ping(ip_queue):
    while True:
        ip = ip_queue.get()
        if ip is None: # Loop until sentinel encountered
            return
        print("Pinging ip: " + ip)# Construct a queue, rather than a simple list
ip_queue = queue.Queue()# Ask user for IP address, place onto queue
for x in range (4):
    ip = input("please enter ip: ") # No need for str(), input() already returns a string
    ip_queue.put(ip)# Calls function _ping with threading.
if __name__ == '__main__':
    numOfThreads = 2
    threadList = []    # Place sentinels for each thread
    for i in range(numOfThreads):
        ip_queue.put(None)    # Start each thread
    for i in range (numOfThreads):
        t = threading.Thread(target=_ping, args=(ip_queue,))
        t.start()
        threadList.append(t)    # Usually good practice to wait for each thread
    for thread in threadList:
        thread.join()
Philip Jay Fry ответил: 13 июня 2018 в 03:58
Просто хотел добавить. Мне просто нужна была помощь с логикой, и этот пример дал мне это. Взяв это, я смог взять текстовый файл, полный IP-адресов, добавить их в очередь, пронести их с помощью потоковой передачи и поместить успешные пинги в очередную очередь, а затем с помощью потоковой передачи я web очистил эти IP-адреса. Процесс, используемый для получения 5 часов, теперь занимает 30 минут. Благодаря!
atline ответил: 13 июня 2018 в 01:09

Предложите использовать threadpool, сначала используйте pip install threadpool для установки модуля, затем выполните следующий код:

import threadpooldef ping(ip):
    print("Pinging ip: " + ip)if __name__ == '__main__':
    ip_list = []    for x in range (0, 4):
        ip = str(input("Please enter ip: "))
        ip_list.append(ip)    numOfThreads = 2
    pool = threadpool.ThreadPool(numOfThreads)    requests = threadpool.makeRequests(ping, ip_list)
    [pool.putRequest(req) for req in requests]
    pool.wait()
Philip Jay Fry ответил: 13 июня 2018 в 04:00
Я не пробовал это, так как у меня все работает с первым сообщением. Спасибо за ответ tho!

Дополнительное видео по вопросу: Как использовать поток для следующего объекта, который еще не использовался?

Курс программирования: Python 3.x Threading №0

#56 Python Tutorial for Beginners | MultiThreading in Python

Python Threading Tutorial