Есть такая задача: принимать соединения по сокетам, получать входные данные для сложных вычислений, вычислять и отдавать ответ. Запросов одновременно может быть очень много.
Сначала я понял, что из-за GIL я не смогу использовать нормально потоки, и пробовал обернуть всё в C++, подключая boost:threads и boost:python, запуская потоки в C++ и производя вычисления в каждом потоке в субинтерпретаторе python, но нифига не вышло, всёравно проц с 8 ядрами не юзался на 100%.
В итоге я решил, что придётся только через multiprocessing, и оптимально будет создать сразу n worker'ов (кол-во ядер*2), чтобы они сидели и ждали заданий. Таким образом не тратится время на создание процесса, и они не расплодятся более чем n количество.
С сокетами и потоками я больше работал в C++, поэтому в python'е только сталкиваюсь с этим.
Есть такой скрипт:
#!/usr/bin/env python import multiprocessing as mp import logging import socket import time logger = mp.log_to_stderr(logging.DEBUG) def worker(socket): while True: client, address = socket.accept() logger.debug("{u} connected".format(u=address)) #hard and long calculations client.send("OK") client.close() if __name__ == '__main__': num_workers = 5 serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.bind(('',1111)) serversocket.listen(5) workers = [mp.Process(target=worker, args=(serversocket,)) for i in range(num_workers)] for p in workers: p.daemon = True p.start() while True: try: time.sleep(10) except: break
Сейчас он создаёт 5 воркеров, но больше 5 он соединений не примет.
Нужно переделать его, чтобы создавалась очередь из этих соединений, т.е. по сути worker выполнил вычисления и закрыл соединение, освободившись, и взял следующий сокет.
Знатокам потребуется добавить сюда пару строчек, только вот каких… прошу помочь