This commit is contained in:
lovinervy committed 2026-10-07 13:06:47 +05:00
commit c394677d07
59 files changed
+5149

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
# Типичные ошибки и как их избежать
Сборник реальных проблем, с которыми сталкиваются студенты на этом курсе.
Прочитайте перед началом работы — сэкономит часы отладки.
## 1. `multiprocessing` на Windows: `BrokenProcessPool` / бесконечный цикл
**Симптом:** при запуске кода с `Pool` или `Process` на Windows процесс
перезапускается бесконечно или падает с ошибкой пиккелинга.
**Причина:** Windows использует метод запуска `spawn` — каждый дочерний
процесс заново импортирует ваш модуль. Если создание воркеров не защищено,
оно повторяется в каждом импорте.
**Лечение:** весь код создания процессов — только под
`if __name__ == "__main__":`. Это правило №1 курса.
```python
def main():
with Pool(4) as pool:
...
if __name__ == "__main__":
main()
```
## 2. «Мой параллельный код медленнее последовательного»
**Причины по частоте:**
1. Накладные расходы (запуск процесса ~10–100 мс, передача данных через
pickle) больше, чем выгода, — работа слишком мелкая.
2. GIL: потоки на CPU-bound задаче не ускоряют, а только добавляют
переключения.
3. Слишком много частей: 10 000 задач по 1 мс — плохо; 4–8 частей по
100 мс — хорошо.
**Что делать:** это не ошибка, а результат для анализа. Опишите его в отчёте —
именно это и является целью курса.
## 3. Результат параллельного запуска не совпадает с последовательным
**Причины:**
- результат зависит от порядка сборки частичных результатов;
- несколько воркеров изменяют общую структуру без синхронизации (гонка);
- случайные данные без фиксированного seed.
**Лечение:** в этом курсе все задачи устроены так, что checksum не зависит от
разбиения. Если не совпадает — ищите гонку или неверную сборку.
## 4. Дедлок в producer–consumer
**Симптом:** программа висит и не завершается.
**Частые причины:**
- потребитель ждёт `queue.get()` в бесконечном цикле, а производитель уже
закончил — используйте `queue.put(None)` как «маркер конца» или
`queue.close()` + `join_thread()`;
- `pool.apply()` без закрытия пула;
- ожидание события, которое никто не установит.
**Отладка:** добавьте print перед/после каждого get/put — сразу видно, кто
кого не дождался.
## 5. `asyncio.run()` нельзя вложить
**Симптом:** `RuntimeError: asyncio.run() cannot be called from a running
event loop`.
**Причина:** попытка запустить event loop внутри уже работающего (например,
из Jupyter).
**Лечение:** один `asyncio.run(main())` на программу, вызывается из обычного
синхронного кода.
## 6. Забыли `await`
**Симптом:** `RuntimeWarning: coroutine ... was never awaited`, код
выполняется мгновенно и ничего не делает.
**Причина:** вызов корутины без `await` создаёт объект корутины, но не
запускает её.
**Лечение:** `await корутина()` — всегда.
## 7. Кириллица «кракозябрами» в консоли Windows
```bat
chcp 65001
```
или запуск через `python -X utf8 файл.py`. В VS Code терминал обычно уже UTF-8.
## 8. `pytest` не находит модуль студента
**Причина:** тесты запускаются не из корня курса, или solution.py лежит не там.
**Лечение:** запускать `python -m pytest tests/ -k labXX` строго из корня
курса; `solution.py` — в папке своей лабораторной.
## 9. Замеры «прыгают»
- закройте браузер/IDE-мессенджеры на время замеров;
- на ноутбуке подключите питание (троттлинг на батарее режет частоту вдвое);
- берите лучшее время из ≥3 повторов (`time_call`);
- не замеряйте в отладчике.
## 10. Списывание
Код проверяется и на совпадение между собой, и на понимание при защите.
Варианты у всех разные (см. `common/варианты.md`) — чужой вариант виден сразу.