• XSS.stack #1 – первый литературный журнал от юзеров форума

Потоки Python

Undergrowth

(L3) cache
Пользователь
Регистрация
14.05.2024
Сообщения
174
Решения
1
Реакции
111
Хотел отсканировать nuclei'ем ip и большой список ему трудно запустить. Начал переписывать на python с использованием ленивого чтения, чтобы сразу запускалось всё, но проблема в том, что асинк корутины работают в одном потоке, хоть создам 100000 тасков от них смысла мало. Вопрос какой яп дает нормальные потоки, чтобы они распределяли нагрузку на всё cpu?

если что-то неправильно описал, то исправьте меня. Мб чего-то не понимаю)
 
Как я понимаю у тебя сканер/чекер? они не нагружают ЦПУ, они нагружают I/O подсистему, тк бОльшую часть времени ждут ответа по сети.
Про распределение нагрузку потоков на цпу. Хочу грубо говоря сделать 10-20к корутин реальных, а то если в питоне указать столько это не будет (инет позволяет)
 
Последнее редактирование:
Про распределение нагрузку потоков на цпу. Хочу грубо говоря сделать 10-20к корутин реальных, а то если в питоне указать столько это не будет (инет позволяет)
у тебя сетевая карта вывезет и раутер и прочее? ты упираешься не в процессор а в сетевую подсистему) процессор там по сути чисто пакет сформировал и скормил вниз по OSI. Это все как раз можно на раутере/маршрутизаторе смотреть в реалтайме.
Плюс не забудь, каждый открытый сокет - это файловый дескриптор в линуксе, ulimit по дефолту у бубунты 1024
У меня питон c asincio на хорошей машине тянул до 100к активнх соединений, нагрузка на цпу была около 5-15% (Core i9 11500k), потребелние памяти тоже какое-то смехотворное типа 1гб, а вот свитч оказался не готов к таким приколам)
 
у тебя сетевая карта вывезет и раутер и прочее? ты упираешься не в процессор а в сетевую подсистему) процессор там по сути чисто пакет сформировал и скормил вниз по OSI. Это все как раз можно на раутере/маршрутизаторе смотреть в реалтайме.
Плюс не забудь, каждый открытый сокет - это файловый дескриптор в линуксе, ulimit по дефолту у бубунты 1024
У меня питон c asincio на хорошей машине тянул до 100к активнх соединений, нагрузка на цпу была около 5-15% (Core i9 11500k), потребелние памяти тоже какое-то смехотворное типа 1гб, а вот свитч оказался не готов к таким приколам)
А можешь показать пример реализации ? Думаю вывезет, просто интересно это сделать (у меня сервер)
 
Python:
import websockets
import asyncio
import sys

async def url_check(host_port):
    is_ok = False
    try:
        # read
        async with websockets.connect(host_port) as websocket:
            await websocket.send('say hello')
            resp = await websocket.recv()
            if "data is ok" in resp:
                is_ok = True
    except Exception as e:
        # raise e
        pass

    return is_ok

async def check_ports():
    coros = [ url_check(f"192.168.1.1:{x}") for x in range(0, 65535) ]
    ok_list = await asyncio.gather( *coros )
    print(ok_list)

if __name__=='__main__':
    asyncio.run( check_ports() )
    sys.exit(0)

простой пример, взял вэбсокеты для иллюстрации. Можно заменять на все что душе угодно, обычные сокеты (но они будут блочить исполнение aioloop'а), aio sockets, aio-http-запросы и тд. Можно скармливать листы (дробя их на чанки) и тд и тп.
Если есть хоть какая-то панель контроля сети, то на ней как раз будет видно реальное число соединений, поднятых сервисом.
 
Python:
import websockets
import asyncio
import sys

async def url_check(host_port):
    is_ok = False
    try:
        # read
        async with websockets.connect(host_port) as websocket:
            await websocket.send('say hello')
            resp = await websocket.recv()
            if "data is ok" in resp:
                is_ok = True
    except Exception as e:
        # raise e
        pass

    return is_ok

async def check_ports():
    coros = [ url_check(f"192.168.1.1:{x}") for x in range(0, 65535) ]
    ok_list = await asyncio.gather( *coros )
    print(ok_list)

if __name__=='__main__':
    asyncio.run( check_ports() )
    sys.exit(0)

простой пример, взял вэбсокеты для иллюстрации. Можно заменять на все что душе угодно, обычные сокеты (но они будут блочить исполнение aioloop'а), aio sockets, aio-http-запросы и тд. Можно скармливать листы (дробя их на чанки) и тд и тп.
Если есть хоть какая-то панель контроля сети, то на ней как раз будет видно реальное число соединений, поднятых сервисом.
да, это всё круто, но у меня так же. Надо как-то грамотней сформулировать свою мысль
 
я тебе уже написал - дело не в процессоре а в сети и ее ограничениях (не ограничение в ширине канала а ограничение в количестве одновременных соединений у сетевой карты и далее по списку). когда ты это поймешь, все вопросы отпадут.
 
Вопрос какой яп дает нормальные потоки, чтобы они распределяли нагрузку на всё cpu?
если что-то неправильно описал, то исправьте меня. Мб чего-то не понимаю)
Исправляю: доступ к многопоточности как правило даёт операционная система, а не язык программирования. Соответственно, язык может быть любой нормальный.

Код:
import win32api
import win32con
import win32process

def worker():
    # Код, выполняемый в потоке
    pass

# Создание и запуск потока
thread_id, thread_handle = win32api.CreateThread(None, 0, worker, None, 0, None)
win32api.CloseHandle(thread_handle)
 
, но проблема в том, что асинк корутины работают в одном потоке,
Проблема в том что ты не понимаешь как они работают. Что бы нормально рабтать с асинками надо понимать что такое порт завершения ввода вывода. Упрощенно это выглядит так - Вызывается системное апи которое куда то передает задание(например конект) а у тебя остается объект эвент, железка например сетевая карта пытается кудато конектится(здесь вообще нет речи о треде, все происходит в отдельной железке) когда у нее что то получается или не получается оно генерирует прерывание, прерываение получет ос и выставляет тебе твой объект эвент в сигнальное состояние, вот считай что gather это как бы обертка над ожиданием множества эвентов(WaitForMultipleObjects). Какие то разговоры что это работает в каком то там потоке это вообще нелепо.
 
я тебе уже написал - дело не в процессоре а в сети и ее ограничениях (не ограничение в ширине канала а ограничение в количестве одновременных соединений у сетевой карты и далее по списку). когда ты это поймешь, все вопросы отпадут.

Исправляю: доступ к многопоточности как правило даёт операционная система, а не язык программирования. Соответственно, язык может быть любой нормальный.

Код:
import win32api
import win32con
import win32process

def worker():
    # Код, выполняемый в потоке
    pass

# Создание и запуск потока
thread_id, thread_handle = win32api.CreateThread(None, 0, worker, None, 0, None)
win32api.CloseHandle(thread_handle)

Проблема в том что ты не понимаешь как они работают. Что бы нормально рабтать с асинками надо понимать что такое порт завершения ввода вывода. Упрощенно это выглядит так - Вызывается системное апи которое куда то передает задание(например конект) а у тебя остается объект эвент, железка например сетевая карта пытается кудато конектится(здесь вообще нет речи о треде, все происходит в отдельной железке) когда у нее что то получается или не получается оно генерирует прерывание, прерываение получет ос и выставляет тебе твой объект эвент в сигнальное состояние, вот считай что gather это как бы обертка над ожиданием множества эвентов(WaitForMultipleObjects). Какие то разговоры что это работает в каком то там потоке это вообще нелепо.
Спасибо всем
 
Проблема в том что ты не понимаешь как они работают. Что бы нормально рабтать с асинками надо понимать что такое порт завершения ввода вывода. Упрощенно это выглядит так - Вызывается системное апи которое куда то передает задание(например конект) а у тебя остается объект эвент, железка например сетевая карта пытается кудато конектится(здесь вообще нет речи о треде, все происходит в отдельной железке) когда у нее что то получается или не получается оно генерирует прерывание, прерываение получет ос и выставляет тебе твой объект эвент в сигнальное состояние, вот считай что gather это как бы обертка над ожиданием множества эвентов(WaitForMultipleObjects). Какие то разговоры что это работает в каком то там потоке это вообще нелепо.
Имел ввиду сама программа работает в одном потоке cpu и она грузится на 100%, когда другие стоят по нулям. Хотелось бы просто распределить ее, чтобы остальное не пустовало, а то как то странно выходит.
1723652942839.png
 
Имел ввиду сама программа работает в одном потоке cpu и она грузится на 100%, когда другие стоят по нулям. Хотелось бы просто распределить ее, чтобы остальное не пустовало, а то как то странно выходит.
Посмотреть вложение 92620
Грузит какими действиями? Смотри все эти асинк либы имеют в своем имени io, что говорит тебе об асинхронности ввода вывода. Тоест допустим за 1 мсек ты можешь дать сетевухе одну команду а сетевухе что бы законектится надо аж 3секунды, и вот ты скажем за 1секунду запихнул в сетевуху 1к заданий на конект и в течении 3х секунд получил свои конекты. Вот в этом смысл асинков и в этом их профит, что у тебя за 3 секунды сделалось 1к заданий. Ты не сможешь создать 1к тредов, а если сможешь то результат тебе не понравится. Далее получив свои конекты ты же что то с ними делаешь? Вот все что ты делаешь в своем треде, запихивая задачи в сетевуху или обрабатывая как то полученные результаты грузит твой проц. Асинхронное программирование это сложная тема, она требует четкого понимание как и что работает что бы проектировать эффективные программы. Ты всегда должен понимать что будет происходить и знать узкие горлышки задачи.
 
Возможно тебе обработку каких то полученных данных от ио надо предавать пуллу потоков, ты ведь вкурсе про пулл потоков? Хотя в пайтоне с потоками туго, тоже надо понимать где ты будешь упиратся в критические секции.
Вообще пайтон это не инструмент на котором можно хорошо делать все на свете. Асинхронно и многопоточно работать с сетью как я понимаю проще всего на ГО, он для этого и был заточен.
 
Грузит какими действиями? Смотри все эти асинк либы имеют в своем имени io, что говорит тебе об асинхронности ввода вывода. Тоест допустим за 1 мсек ты можешь дать сетевухе одну команду а сетевухе что бы законектится надо аж 3секунды, и вот ты скажем за 1секунду запихнул в сетевуху 1к заданий на конект и в течении 3х секунд получил свои конекты. Вот в этом смысл асинков и в этом их профит, что у тебя за 3 секунды сделалось 1к заданий. Ты не сможешь создать 1к тредов, а если сможешь то результат тебе не понравится. Далее получив свои конекты ты же что то с ними делаешь? Вот все что ты делаешь в своем треде, запихивая задачи в сетевуху или обрабатывая как то полученные результаты грузит твой проц. Асинхронное программирование это сложная тема, она требует четкого понимание как и что работает что бы проектировать эффективные программы. Ты всегда должен понимать что будет происходить и знать узкие горлышки задачи.
спасибо услышал ответ!
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх