Разница между Data Race и Race Condition

Рассмотрим разницу между популярными ошибками при работе с многопоточностью, такими как Data Race и Race Condition, а также способами борьбы с ними.

Распараллеливаем вычисления

Рассмотрим разницу между популярными ошибками при работе с многопоточностью, такими как Data Race и Race Condition, а также способами борьбы с ними.

Привет, Хабр! Я Артём Чаадаев из команды ассортимента размещения в Туту и занимаюсь разработкой на языке Go. Здесь мы посмотрим как решить распространенную практическую задачу применяя паттерны Semaphore и Worker Pool.
Хотите научиться конкуретной разработке на Go? Значит, вам сюда.
Добро пожаловать под кат!
Делая свой очередной пет-проект подумал, что мне нужна конкурентная очередь с приоритетами. Оказалось она была не нужна, но желание ее реализовать никуда не ушло.
Проведя небольшой поиск, нашел несколько научных статей с конкурентной реализацией и выбрал одну в качестве образцовой.
Потратив время и нервы на ее понимание и реализацию, был отрицательно удивлен результату: ее производительность хуже чем глобальная блокировка на всю структуру данных.
Здесь описал свою реализацию и сделал сравнение с блокирующей реализацией.
Критика (даже не конструктивная) приветствуется.

Создались условия, чтобы подвести некий итог. Дело в том, что автоматы в SimInTech могут быть инерционными. И это определенно знаменательный факт. Более того, он даже радует своей неожиданностью, опровергая то фактическое неверие, которое к среде было до этого. Но давайте подробнее о том, как это все таки случилось...

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

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

Что надо знать, чтобы успешно применять-реализовать многопоточность (Multithreading) в своей программе? Мне кажется есть некоторые неудобные для изложения куски в разных описаниях потоков и того, что с ними связано, которые остаются не раскрытыми или вообще пропускаются.
Мне хочется предложить на суд читателей мое собственное понимание таких неудобных аспектов, связанных с применением многопоточности для практического программирования, которое накопилось у меня за пару десятилетий успешного применения этой самой многопоточности на всех уровнях разработки от Embedded и аппаратно-ориентированных уровней до C#, WPF, Java высокоуровневых фронт-ендов.

Конечные автоматы и соответственно автоматное программирование (АП) интересны в первую очередь параллелизмом и эффективностью его реализации. Причем параллелизм у КА присутствует уже на уровне компонентного КА, но несомненно важнее параллелизм сетей автоматов. На примере простого алгоритма НОД было показано, как можно легко превратить любой алгоритм в процесс, а затем из них создать более сложную схему. «Сетевая конструкция» позволяет эффективно представлять параллельные процессы и создает понятную, простую и теоретически обоснованную теорию параллельных вычислений (см. подробнее [3]).
Модель отдельного КА определяет точки и механизмы взаимодействия (здесь вспоминаем про состояния) между параллельными процессами. Состояния автомата фиксируют моменты программного и/или аппаратного прерывания/приостановки/взаимодействия процессов (см. автоматный код НОД в статье). И не важно идет ли речь идет об имитации параллелизма в рамках одного потока или это будет множество потоков или даже ядер, т. е. того, что в иной подаче звучит как in parallel и concurrently. И здесь уже надо говорить об едином времени подобно единому времени реальных процессов. Соответственно, уточняя при этом, что на формальном уровне речь идет о сетевой автоматной модели с единым дискретным временем. При этом допускается, что разные сети вправе иметь индивидуальное дискретное время.
Дискретное время — важнейший элемент автоматной модели. Оно, как и состояния, зашито в определении модели. И уже только состояния и дискретное время выделяют автоматы на фоне других моделей. Дискретное время играет важнейшую роль в формировании качественно иной, например, по отношению к той же многопоточности или многоядерности, модели и теории параллельных вычислений. Важно также понимать, что любые асинхронные сети такой теории не имеют. Можно даже утверждать, что теория параллелизма на базе КА не была бы возможна без дискретного времени и, конечно, состояний. И актуальны они именно в своей «связке».

В этой статье мы рассмотрим, как и почему изменилась реализация примитивов синхронизации из стандартной библиотеки Java и пакета java.util.concurrent для Kotlin Coroutines и для языка Kotlin в целом.
Разберемся, какие реализации примитивов синхронизации потоков актуальны в контексте корутин, а какие надо использовать с осторожностью.
Оценим готовность текущих решений к использованию в Kotlin Multiplatform.
Разработаем аналоги нескольких полезных классов пакета java.util.concurrent, до которых еще не добрались разработчики корутин.
В рамках статьи будут разобраны следующие примитивы синхронизации: критические секции, атомарные переменные, реактивные переменные и барьерная синхронизация.

Золотые времена подошли к концу, когда разработчикам можно было ничего не делать, а программное обеспечение работала с каждым годом все быстрее.

На рис. 1 приведена блок-схема алгоритма нахождения наибольшего общего делителя двух натуральных чисел из книги Н. Вирта[1]. С таких алгоритмов, да и с подобных книг, начинается или должно начинаться знакомство с программированием. И, кстати, книга Н.Вирта была одной из первых, с которой в свое время познакомился и я. Так что здесь присутствует и некий личный мотив.
На старте вашей карьеры вы вполне можете обойтись без практических навыков в параллельном программировании, но рано или поздно перед вами встанет задача, требующая от вас таких навыков.
Итак, в данной статье мы поговорим о многопоточности в Java. Тема очень обширная, и я не ставлю целью описать все ее аспекты. Статья рассчитана на людей, только начинающих свое знакомство с многопоточностью. В данной статье мы рассмотрим основу многопоточности Java, такие базовые механизмы синхронизации как ключевые слова volatile и synchronized и очень важную проблематику “Состояние гонки” и “Смертельная блокировка”.
Я выбрал немного необычный подход, связав технические примеры с нащей повседневной жизнью, надеюсь вам понравится. Тема будет раскрыта на примере абстрактной комнаты и людей в находящихся в ней.
Дабы максимально упростить материал, я намеренно буду опускать некоторые нюансы реализации и иерархии многопоточности в Java, усложняющие понимание темы. Если вы рассчитываете на подробный обзор с техническими терминами и формулировками, то данная статья вам не подойдет.

В этой части серии статей про разработку сервера для реалтайм игр я расскажу вам о показателе сетевого устройства которое значительно влияет на количество запросов, которое способен обработать ваш игровой сервер.
В статье я расскажу как разработчиков вводят в заблуждение рассказывая что необходимо учесть в первую очередь при разработке серверов (и не только для игр), но умалчивая о реальных "узких местах" (проблемах).
В конце статьи будет приложена видео версия.

В данной статье речь пойдет о взаимодействии WebSocket сервера и сервера рассчитывающего события в мультиплеерных играх (команды пользователей, игровую физику, алгоритмический искусственный интеллект и т.п.).
Будет затронута тема очередей, асинхронного логирования, параллельного программирования на CPU и использования каналов (сhannel) для взаимодействия между процессами (thread - ветками) на языке программирования PHP (аналогичный функционал есть в языке GO).

Одной из главных фишек языка Go является удобная работа с конкурентностью. Однако, в больших проектах всё равно возникают такие проблемы как утечка горутин, некорректная обработка паник в горутинах, плохая читаемость кода.
Как указывает автор библиотеки в своей статье, он часто сталкивается с подобными проблемами и связанными с ними ошибками при работе с горутинами, что побудило его создать свою библиотеку conc.
Давайте посмотрим, на что она способна.

Из нашей повседневной практики доподлинно известно, что массивно(массово?)-параллельные вычисления это круто. Но что именно означает этот термин, и как "массивность" и "параллельность" реализованы в конкретной системе? В данной статье мы ответим на оба вопроса, проанализировав внутреннюю архитектуру популярного MPP-движка для больших данных Trino.

В первой части статьи мы рассмотрели написание на современном Фортране простой программы, реализующей клеточный автомат "Жизнь", в виде классического последовательного кода (SISD), матричных операций (SIMD) и параллельных конструкций SMP (SIMD с частью функций MIMD). Сейчас мы будем рассматривать использование конструкций Фортрана для программирования массивно-параллельных архитектур (MPP), к которым, в частности, относятся современные суперкомпьютеры. Такие архитектуры реализуют классическую схему MIMD.
В этой статье мы попробуем написать простейшую параллелизуемую программу на языке Фортран, используя для этого методы конвейеризации и симметричной параллелизации и сравним их между собой, применив наиболее популярные компиляторы GNU Fortran и Intel Fortran.

Вы замечали, как простые вопросы иногда приводят к сложным вопросам? Сегодня мы попытаемся подступиться к одному из таких вопросов. Категория — наша любимая: сетевые аспекты Linux.