Динамическая проверка строк в txt и запуск/остановка потоков по строкам

224 просмотра
0
0 Комментариев

Есть рабочий скрипт, который запускает поток с функцией на каждую строку загруженного txt:

def work():
   while True:
        requests.get(line)
        time.sleep(11)
 
for line in base:
    threading.Thread(target=work,args=(line)).start()

вопрос: как сделать так, чтобы например каждую минуту строки в base.txt проверялись повторно, и если одну строку удалили- ее поток завершался, а если добавили- то стартовал новый поток с этой строкой?
В base.txt содержатся адреса сайтов, с новой строки каждый, например:

mysite.com
yoursite.com

В фунцкии work бесконечным циклом к этим сайтам идет запрос и проверка определенной информации


Добавить комментарий

2 Answers

Python Опубликовано 09.12.2018
0

Наверно как-то так:

while True:
    # Открываем файл и делаем список из строк
    with open('base.txt') as f:
        base = f.readlines()
 
    # Проверяем каждую строку на наличие потока с таким же именем
    # Если потока нет, то стартуем его
    for line in base:
        if line not in current_threads:
            current_threads.append(line)
            threading.Thread(target=work, name=line).start()
 
    # Проверяем есть ли в списке запущенных потоков такие, которых нет
    # в файле. Если есть лишние, то удаляем их из списка активных потоков.
    new_thred_list = []
    for thread in current_threads:
        if thread in base:
            new_thred_list.append(thread)
    current_threads = new_thred_list
 
    sleep(60)

В функцию work добавляем проверку на актуальность данного потока

if threading.current_thread().name not in current_threads:
    break

break разорвет цикл while в функции work, тем самым завершит соответствующий поток

Добавить комментарий
0

Попытка убить потоки снаружи указывает на ошибку в дизайне программы. Потоки следует останавливать (если это вообще оправданно), только с кооперацией с их стороны. Это не случайность, что нет Thread.stopметода, в отличии от к примеру Process.terminate.

Чтобы периодически выполнять функцию в отдельных потоках и запускать/останавливать выполнение отдельных циклов повторения раз в минуту в соответствии с текущим содержимым входного файла, можно call_repeatedly() использовать и простой временно́й цикл:

import time
 
stop_calls_to = {}  # hostname -> cancel future calls
while True:
     with open('base.txt') as file:
         hostnames = set(filter(None, map(str.strip, file)))
 
     # stop calls to hostnames that are not in base.txt
     for hostname in (stop_calls_to.keys() - hostnames):
         stop_calls_to[hostname]()
         del stop_calls_to[hostname]
 
     # add new repeating calls from base.txt
     for hostname in (hostnames - stop_calls_to.keys()):
         stop_calls_to[hostname] = call_repeatedly(11, check_site, hostname)
 
     time.sleep(60)  # wait a minute until the next sync

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

При большом количестве сайтов, лучше асинхронные вызовы использовать (к примеру, с помощью aiohttp) вместо создания отдельного потока для каждого сайта.

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up