Внедрение параллельности в однопоточный язык, не нарушающее совместимости

Если типичный императивный язык программирования был в начальной задумке однопоточным, то наивное добавление в него многопоточности не может быть осуществлено без слома совместимости, так как нарушает фундаментальное свойство, гарантирующее неизменность доступных переменных при отсутствии их изменений со стороны самого потока. Приёмы работы с данными, которые были совершенно приемлемы в однопоточности, могут оказаться неадекватными в многопоточном. Такой слом в языке не является чем-то совсем недопустимым, если сама платформа зарождалась в такой среде и накопление кода всегда происходило с учётом этой особенности. Но даже в этом случае достижение правильности кода избыточно перекладывается на плечи программиста с сопутствующими результатами. Такой подход неприемлем для языков, создаваемых не только для того, чтобы не мешать, но и для того, чтобы помогать. Что можно предложить для них?

Основа

Исходные свойства должны оставаться неизменным для данных и действий, объявленных в соответствии с исходной однопоточной спецификацией языка, а нововведения в ожидаемых эффектах должны предоставляться только через нововведения же в языке. В том числе это означает, что для потока по-прежнему верно, что обычные переменные не могут измениться как-то иначе, кроме как в самом этом потоке. И тонкая грань, пролегающая между ломающим внедрением параллельности и совместимым, заключается почти исключительно в трактовке понятия глобальности. В первом случае она считается абсолютной, а во втором — относительной. Последнее означает, что потоки преимущественно логически изолируются друг от друга и большей частью своего состояния распоряжаются единолично, что гарантируется языком, а не просто дисциплиной разработчика. Важно отметить, что изоляция хороша не только для параллельности.

Такой подход можно назвать многооднопоточностью. В ней запущенный параллельно код, даже если он никогда для этого не предназначался, не вступит в противоречие с другим потоком и будет выполняться ровно так же, как в однопоточной среде. В худшем случае это приведёт лишь к дополнительному расходу памяти из-за избыточного дублирования. Но не жертвуя корректностью систему можно постепенно дорабатывать, объединяя те данные, для которых это уместно. Работу с данными, общими по своей природе, в любом случае необходимо дорабатывать относительно однопоточного кода.

Добавление

Обмен данными между потоками возможен через:

Примечания [0] Речь идёт о гарантиях отсутствия блокировок на уровне терминов языка. Понятие блокировки может быть воспроизведено в других терминах. Смотрите, например, код получения взаимных блокировок в однопоточном языке, запускаемом в многозадачной среде.
Смотрите также Рифат Сабирзянов - Concurrency with shared variable considered harmful на YouTube