Сегодня посмотрим как смоделировать программу с конкурентностью на FSP. Сначала давайте разберемся, зачем вообще нужна конкурентность. Вот что можно сделать с её помощью:
Сгенерированная инструментом LTSA диаграмма состояний
Finite state processes (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) .
У процесса техника несколько вариантов действий. Но при синхронизации процессов техника и студента блокируется вариант немедленного завершения.
Анимация процесса техника
|| 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.
КУРСЫ
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…
У частных продавцов на Авито появилась возможность составлять текст объявлений с помощью нейросети. Новый функционал доступен в категории «Обувь, одежда,…
24 апреля 2024 года в Москве состоялась церемония вручения наград международного конкурса Workspace Digital Awards. В этом году участниками стали…
27 июня Яндекс проведет гик-фестиваль Young Con для студентов и молодых специалистов, которые интересуются технологиями и хотят работать в IT.…