Делаем систему параллелизма надёжнее
Сегодня посмотрим как смоделировать программу с конкурентностью на FSP. Сначала давайте разберемся, зачем вообще нужна конкурентность. Вот что можно сделать с её помощью:
- Повысить производительность многопроцессорного железа, это и называется параллелизм;
 - Увеличить пропускную способность приложения (вызову ввода-вывода нужно блокировать только один поток);
 - Сделать приложение отзывчивее за счёт выполнения основных задач параллельно фоновым (высокоприоритетный поток для запросов пользователей);
 - Структурировать программу, повысив её эффективность (взаимодействующие со средой программы управляют несколькими действиями и обрабатывают несколько событий).
 

Сгенерированная инструментом LTSA диаграмма состояний
Что это за язык — FSP?
Finite state processes (FSP) — это абстрактный язык, на котором разрабатывают системы конкурентных процессов.
Мы моделируем предлагаемую архитектуру, чтобы добавить уверенности в её обоснованности и адекватности. Параллелизм, как и большинство сложных задач проектирования, лучше всего разбирать с помощью нескольких слоёв абстракции.
Во-первых, нам нужно ясно понять функциональные требования к системе, в том смысле, какого поведения мы от неё хотим. Затем нужно изучить возможные роли параллелизма. Лучше всего сделать это с помощью абстрагирования потоков без привязки к конкретной реализации.
Окончательный выбор механизмов реализации параллелизма должен оставаться открытым, насколько это возможно, чтобы позволять тонко настраивать производительность и гибкость распределения компонентов, различные в разных конфигурациях продукта.
Как с помощью алгебры процессов (FSP) описать конкурентные процессы
Легче объяснять понятия и модели на примере. Проанализируем и смоделируем ситуацию, когда два студента. чтобы распечатать документы, вместе пользуются принтером, а техник заполняет принтер листами.
Вначале проанализируем принтер
- В принтер помещается только три листа, студенты могут распечатать до трёх документов;
 - Если листов нет, принтер нужно заполнить ими.
 
const MIN_SHEET_COUNT	=	1
const MAX_SHEET_COUNT	=	3
range DOC_COUNT		=	MIN_SHEET_COUNT .. MAX_SHEET_COUNT
range SHEET_STACK	=	0 .. MAX_SHEET_COUNT
PRINTER(SHEETS_AVAILABLE = MAX_SHEET_COUNT) =  ( start -> PRINTER_AVAILABLE[MAX_SHEET_COUNT]),
  PRINTER_AVAILABLE[sheets_available: SHEET_STACK] = 
	if   (sheets_available > 0)
	  then (acquire -> print[DOC_COUNT] -> release -> PRINTER_AVAILABLE[sheets_available - 1])
	  else (empty -> refill_printer -> release -> PRINTER_AVAILABLE[MAX_SHEET_COUNT]).
Процесс PRINTER
Когда пользователь (студент или техник) получает принтер, принтер печатает документ, отдаёт его пользователю и возвращается в исходное состояние. Это называется повторяющимся поведением.
Как анимировать процесс
Чтобы анимировать процесс, сначала скомпилируйте (compile [1]) код, затем перейдите на вкладку draw. Нажмите кнопку animatе [2].

Анимация процесса PRINTER
В аниматоре видно, что принтер напечатал три документа и пошёл на заправку. Заправлять принтер должен техник. Эту часть мы проанализируем позже.
Печатающий документы студент
Код на FSP можно написать при помощи условных процессов (if, then, else). DOCSTOPRINT = 3 — это переданный процессу параметр 3. Процесс PRINT начинается с 0. Doc_count — это метка индексированного действия, которая ведёт к этому действию: PRINT [doc_count].
STUDENT(DOCS_TO_PRINT = 3) =  PRINT[0],
PRINT[doc_count: 0 .. DOCS_TO_PRINT] = 
	if (doc_count < DOCS_TO_PRINT)
	then ( acquire -> print -> release -> PRINT[doc_count + 1]  )
	else ( terminate -> END ).
Процесс STUDENT с условным процессом
Тот же самый процесс можно написать и с помощью защищённых процессов.
STUDENT(DOCS_TO_PRINT = 3) =  PRINT[0],
PRINT[doc_count: 0 .. DOCS_TO_PRINT] = (
  when (doc_count < DOCS_TO_PRINT)  
	acquire -> print -> release -> PRINT[doc_count + 1] |
  when (document_count == DOCUMENTS_TO_PRINT) 
	terminate -> END ).
Процесс STUDENT с защищённым процессом

Анимация процесса STUDENT
Теперь проанализируем техника, который устанавливает бумагу в принтер
TECHNICIAN = (empty -> refill_printer -> release -> TECHNICIAN | terminate -> END) .У процесса техника несколько вариантов действий. Но при синхронизации процессов техника и студента блокируется вариант немедленного завершения.

Анимация процесса техника
Наконец, давайте посмотрим на составной процесс
- Составной процесс должен быть синхронизирован со всеми подпроцессами, для этого можно определить набор действий с именем PRINT_Actions.
 - terminate/s1.terminate — это перемаркированное действие. С помощью мы переназначаем действие s1.terminate, чтобы просто завершить процесс. В противном случае аниматор покажет s1.terminate, s2.terminateиtcn.terminate.
 - Чтобы синхронизировать пользователей с PRINTER, можно использовать взаимоисключающий общий ресурс.
 
|| SHARED_PRINTER = (s1: STUDENT(2) || s2: STUDENT(3) || tcn : TECHNICIAN || All_Users :: PRINTER)Это позволит одному пользователю получить ресурс, а другому — освободить его. Следовательно, когда PRINTER состоит из процессов USER, эта композиция гарантирует, что только получивший ресурс пользователь может освободить его.
const MIN_SHEET_COUNT	=	1
const MAX_SHEET_COUNT	=	3
range DOC_COUNT		=	MIN_SHEET_COUNT .. MAX_SHEET_COUNT
range SHEET_STACK	=	0 .. MAX_SHEET_COUNT
set All_Users = {s1, s2, tcn}
set PRINT_Actions = {acquire, print, release, empty}
PRINTER(SHEETS_AVAILABLE = MAX_SHEET_COUNT) = PRINTER_AVAILABLE[MAX_SHEET_COUNT],
PRINTER_AVAILABLE[sheets_available: SHEET_STACK] = 
		if   (sheets_available > 0)
		then ( acquire -> print -> release -> PRINTER_AVAILABLE[sheets_available - 1]  )
		else ( empty -> release -> PRINTER_AVAILABLE[MAX_SHEET_COUNT] ).
STUDENT(DOCS_TO_PRINT = 1) =  PRINT[0],
PRINT[doc_count: 0 .. DOCS_TO_PRINT] = 
		if   (doc_count < DOCS_TO_PRINT)
		then ( acquire -> print -> release -> PRINT[doc_count + 1]  )
		else ( terminate -> END )+ PRINT_Actions.
TECHNICIAN = (empty -> refill_printer -> release -> TECHNICIAN | terminate -> END) + PRINT_Actions.
|| SHARED_PRINTER = (s1: STUDENT(2) || s2: STUDENT(3) || tcn : TECHNICIAN || All_Users :: PRINTER) 
/ {terminate/s1.terminate,terminate/s2.terminate,terminate/tcn.terminate}.
Составной процесс системы принтера
Я надеюсь, что этот материал поможет вам в изучении параллелизма на FSP.
                        Другие профессии и курсы
                        
ПРОФЕССИИ
КУРСЫ
                    - Профессия Frontend-разработчик
 - Профессия Веб-разработчик
 - Профессия Этичный хакер
 - Профессия C++ разработчик
 - Профессия Разработчик игр на Unity
 - Профессия iOS-разработчик с нуля
 - Профессия Android-разработчик с нуля
 
КУРСЫ
- Курс по Machine Learning
 - Курс «Математика и Machine Learning для Data Science»
 - Курс «Алгоритмы и структуры данных»
 - Курс «Python для веб-разработки»
 - Курс по аналитике данных
 - Курс по DevOps