Какая оптимальная структура сетевого многопоточного приложения на питоне?
Есть задача написать сетевое приложение.
Сервер на питоне 3.7. К серверу по локалке обращаются клиенты, запросы легкие, дать данные, считать данные. Кроме того сервер просчитывает математику по этим данным. Расчет математики запускается по таймеру с периодом около 100 мс. Время ее расчета довольно большое по времени, до 100-200 мс.
Думаю сделать два потока - в одном математика, в другом ввод/вывод. Использовать для этого asyncio и threading (но это не точно). Опыта написания подобных приложений нет и есть несколько вопросов )
1. Из гугла я понял, что потоки фактически работают не паралельно а по одному. То есть получается что поток с математикой может заблокировать ввод вывод?
2. Вообще интерпретатор переключает когда-нибудь потоки по своей инициативе или обязательно ждет, пока один из потоков остановится сам и только тогда запускает другой ?
3. может время от времени принудительно приостанавливать поток с математикой чтобы пошли потоки с вводом-выводом ? и как это сделать? sleep ()?
4. Или я вообще выбрал неверную структуру, может надо как-то иначе ?
Николай, я бы начал с ответа на вопросы
1)по каком протоколу клиенты работают с данным сервером
2)могут ли быть конфликты между клиентами, скажем, один клиенты пытается читать что-то, что меняет другой клиент.
Николай, потому что если клиенты полезут в данные, которые еще не досчитались, они получат мусор. Следовательно, какой смысл выносить расчеты в отдельный поток, если все равно, пока программа считает, клиенты должны ждать
Николай, то есть, у вас должен быть момент синхронизации потоков, когда "решатель" копирует к себе все имеющиеся на данный момент данные и отдает "серверу" посчитанное
Фокс Йовович, данные на сервере видимо будут хранится в трех объектах.
0 -старые данные , уже все посчитано, их получают клиенты когда что то запрашивают
1- текущие, их просчитывает математика.когда закончит, то эти данные станут [0]
2 -новые данные которые присылают клиенты
на саммо деле там чуть сложнее, но вникать смысла нет. я не вижу здесь проблемы , буду блокировать объекты через Lock в момент переключения. момент переключения относительно редкий и короткий.
1) да
2) интерпретатор сам переключает потоки по таймеру
3) смысла нет, GIL сам разберется
4) математику можно вынести в отдельный процесс(multiprocessing, celery, etc), но тогда надо будет так же добавлять сервис общения между ними
Очень походит на задачу с очередью, погуглите rabbitmq, может поможет вам.
Если у вас linux система, то запускать задание можно по crontab. Обращаю ваше внимание, что если программа будет работать дольше, чем время запуска программы, то вы получите накопление процессов и как итог - нестабильное поведение. Избежать этого, можно настроив задание через flock.
Если расчет происходит в 1 поток, то можно и вовсе обойтись без библиотек мультипроцессинга.