Недавно я много читал о функциональных языках. Поскольку они используют только неизменные структуры, они утверждают, что проблемы concurrency значительно улучшены/решены. У меня возникли серьезные проблемы с пониманием того, как это можно реально реализовать в реальном контексте. Предположим, у нас есть веб-сервер с одним потоком, прослушивающим порт (ну, IO - это еще одна вещь, с которой мне сложно оборачивать голову, но пусть просто игнорирует это на данный момент); При любой попытке подключения сокет создается и передается во вновь созданный поток, который выполняет некоторую работу с ним, и, в зависимости от принятых сообщений, может применять изменения в большой структуре списка/данных, которая является глобальной для серверного приложения. Итак, как это работает для доступа к списку, чтобы все потоки имели последовательное представление списка (или, по крайней мере, чтобы все изменения, внесенные одним потоком, примененным к списку, как только поток будет умереть правильно)
Понимание моих проблем:
- Очевидно, что любой поток может получить неизменный "снимок" списка для работы. Однако после "изменения" содержимого путем создания новой версии списка с внесенными изменениями мы по-прежнему остаемся с каждым потоком, имеющим собственную версию списка. Как они объединяются вместе?
- Другой метод может состоять в использовании традиционных механизмов блокировки, таких как mutex/cond или go-like-channels. Однако, как бы вы даже создали такую вещь, когда все переменные неизменяемы?
- Я слышал о STM, однако это не может касаться побочных эффектов (т.е. если список также будет прозрачно архивировать данные в файл или db)
Итак, как бы вы могли моделировать такую вещь на функциональном языке?