Как стать автором
Обновить

Комментарии 11

Допустил ошибку, сравнив Active Record с Doctrine, а не Data mapper pattern паттерн, сорри поправлю

Конкурентность — это способность системы управлять несколькими задачами практически одновременно. Задачи могут приостанавливаться и возобновляться, давая ощущение одновременного выполнения. Это достигается путем распределения времени процессора между задачами.

Что-то мне это определение не нравится. Может, оно для мира PHP/Backend? В моём понимании, конкурентность — это способность управлять доступом к ограниченным ресурсам. А то, что описано выше, — это (псевдо)многозадачность.

соглашусь, предложил альтернативное определение, по проще для понимания

Вопрос немного в сторону: любой ли параллельный код является конкурентным?

Гугл выдает противоположные ответы:

  • Parallelism implies concurrency by definition

  • An application can be parallel, but not concurrent: if it processes sub-tasks of a single task in parallel.

Я в первом лагере, так как приведенный пример не конкурентного выполнения таска - это конкурентное выполнение саб-тасков.

Вот пример: рассчитать таблицу умножения для десятичной системы счисления, то есть заполнить матрицу 10 x 10 значениями, равными произведению номера строки на номер столбца (нумерация начинается с единицы). Для простоты решать будем десятью потоками. Каждому даём свой персональный столбец (или строку) — и вперёд. Параллельность есть? Есть. А где конкурентность?

Параллельность есть? Есть.

Имхо, совершенно не так. 10 тредов - по определению конкурентность. Параллельность зависит на скольких физических ядрах мы запускаем эти 10 потоков. Если у нас 1 ядро - никакой параллельности нет. Есть только конкурентность.

Я на самом деле погуглил еще, и какой-то Computer-Science USA универ тоже приводит пример параллельного, но не конкурентного кода: работа GPU и CPU - они выполняют код параллельно, но не конкурентно. Но имхо, это скорее пример того, что "параллельность" более широкое понятие, которое имеет смысл и вне Software Engineering, когда "concurrency" у нас определенно только в скопе Software Engineering. Два человека живут 2 отдельные параллельные жизни, но конкурентность сюда не относится.

А вот другой американский универ, говорит что "Parallel execution implies that there is concurrency": https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/ParVConc.html

Вообщем, я все же за "Parallelism implies concurrency" и вводил бы определение Parallelism через Concurrency: типа "Parallelism is the special form of concurrency where the multiple tasks (concurrent code) are executed at the same point of time (this is possible only if there are multiple CPU cores or multiple GPU cores)"

Возможно, мы смотрим на вопрос с двух разных точек зрения, поэтому не можем прийти к единому мнению. Попробую пояснить свою позицию. В контексте того примера, который я привёл, понятие параллельности относится исключительно к методу решения задачи. Есть 10 потоков, все они запущены и находятся в состоянии выполнения. Этого достаточно для того, чтобы говорить о параллелизме. То, как этот параллелелизм реализован на низком уровне - реальные ли вычислительные ядра будут выделяться каждому потоку, или потоки будут разделять время работы одного ядра на всех - с точки зрения метода не играет никакой роли. Этот вопрос находится на другом, более низком уровне абстракции, и пусть этот уровень сам решает свои проблемы. Тем более, что из PHP/GO мы никак не можем на это повлиять. Для нас (стороннего наблюдателя прикладного уровня) всё будет выглядеть так, как будто потоки выполняются одновременно.

Главное в приведенном примере то, что потоки могут работать и работают независимо друг от друга. Каждый поток обрабатывает свой набор данных, у них нет предмета для конфликта, а значит и о свойстве конкурентности в данном случае говорить не приходится.

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

Я понимаю, но у вас совершенно не конвенциональное определение параллелизма и конкурентности.

То, как этот параллелелизм реализован на низком уровне - реальные ли вычислительные ядра будут выделяться каждому потоку, или потоки будут разделять время работы одного ядра на всех - с точки зрения метода не играет никакой роли.

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

Каждый поток обрабатывает свой набор данных, у них нет предмета для конфликта, а значит и о свойстве конкурентности в данном случае говорить не приходится.

Это не совсем так, если #CPU < #Threads то потоки будут конкурировать за процессорное время.

Спасибо. Очень пригодилось

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

В случае с race condition допущена неточность. В ЯП с многозадачностью на потоках различают race condition и data race.

Состояние гонки – это когда корректность программы зависит от того, в каком порядке выполняются части кода. Частным случаем является TOCTOU проблема – когда в нескольких потоках делаем некую проверку, а потом исполняем код на основе этой проверки. Например, на балансе лежит 100руб, мы проверяем можем ли купить товар, допустим, за 90руб, и в случае успеха списываем. Если не делать синхронизации и запустить такой код в 2 потоках, то проверка на 100руб > 90руб успешно пройдет в обоих потоках и спишет 180руб, в итоге на балансе станет -80руб.

Гонка данных в свою очередь – это когда несколько потоков читают переменную, и хотя бы 1 поток пишет. Например, в одном потоке мы бегаем в цикле flag = true; while(flag); а в другом потоке меняет флаг flag = false; Без корректной синхронизации такой код может выполняться вечно.

Всё отлично, но от кода на PHP начала 2010х годов (если не раньше) -- глаз дёргается))

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории