Программирование arrow Visual C++ arrow Задача Майхилла для Microsoft Visual C++

Задача Майхилла для Microsoft Visual C++

Оглавление

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

Алгоритм поведения и автоматная модель стрелка

На первый окрик: "Кто идет?" - он стал шутить,
На выстрел в воздух закричал: "Кончай дурить!"
Я чуть замешкался и, не вступая в спор,
Чинарик выплюнул - и выстрелил в упор.
В. Высоцкий

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

Из известных решений данной задачи своей простотой и, главное, "автоматным" подходом привлекает приведенное в работе [2]. Оно заключается в том, что каждый стрелок должен руководствоваться следующим набором указаний.

1. Если ты левофланговый и получил приказ "Шеренга, пли!", то запомни число 1 - свой порядковый номер - и ровно через секунду сообщи его соседу справа.

2. Если ты неправофланговый и сосед слева сообщил тебе число V, запомни число V+1 - свой порядковый номер - и ровно через секунду сообщи его соседу справа.

3. Если ты правофланговый и сосед слева сообщил тебе число n-1, то ровно через секунду ответь ему: "Готов!" и приступай к обратному счету в уме: n, n-1, n-2, ..., отсчитывая по одному числу в секунду.

4. Если ты не правофланговый и сосед справа доложил тебе: "Готов!", то ровно через секунду приступай к обратному счету в уме: V, V-1, V-2, ..., где V - твой порядковый номер, отсчитывая по одному числу в секунду. При этом, если V>1, т.е. если ты не левофланговый, то ровно через секунду после получения сообщения от соседа справа доложи: "Готов!" соседу слева.

5. Досчитав до нуля, стреляй!

Аналогичные указания даются, когда приказ получен правофланговым.

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

На рисунке показан КА, моделирующий поведение стрелка. Стрeлки соответствуют синхронизирующей информации, которая поступает к стрелку от его соседей слева и справа. Предикаты и действия автомата можно условно описать следующим образом:

// Предикаты

x1 Состояние соседа слева "Огонь!"?

// Команда "Огонь";

x2 Состояние соседа справа "Готов!"?

x3 Свой номер не равен нулю?

// Действия

y1 Установить свой номер: взять номер

соседа слева

и увеличить на 1

y2 Уменьшить свой номер на 1

y3 Произвести выстрел

Кстати, эти строки в дальнейшем можно превратить в комментарии к операторам "автоматной программы".


 
« Предыдущая статья   Следующая статья »


  • Visual C++, Работа с СУБД Oracle через интерфейс OCCI
    OCCI - расшифровывается как Oracle C++ Call Interface и представляет собой специализированное апи для работы с СУБД Oracle используя C++ что в общем то явствует из названия. Для использования необходимо подключить заголовочный файл "occi.h"....
  • Visual C++, Использование ODBC в Visual C++
    Класс CDatabase представляет собой класс, который обеспечивает связь с источником данных. Под источником данных может пониматься как непосредсвенно файл, в котором находится таблица, например dBase, так и файл с многими таблицами, например Microsoft Access или сервер баз данных Oracle, MS SQL Server и т.д. Для связи с источником данных используется интерфейс ODBC. У данного класса есть папа в виде класса
  • Visual C++, Создание простого приложения с плагинами
    В этой статье описываются принципы и решения, применяемые при проектировании приложений, которые будут использовать внешние, динамически подключаемые, модули. Эта статья более ориентирована на тех, кто хочет использовать механизмы подключения/отключения функциональности приложения, наподобии механизма Aobe Photoshop или Far, а не просто многократного использования кода в разных приложениях....
  • Visual C++, Работа с 1C Предприятие из Visual C++
    В данной статье показано, как можно работать с 1С Предприятием из С++ с помощью OLE DB. Так же она будет интересна тем, кто не пользуется C++, но хочет узнать подробности "а как оно устроено внутри 1С". В данной статье речь пойдет об 1С Предприятии версии 7.7. Полагаю, что в версии 8 мало что изменилось. Предполагается, что читатель хотя бы чуть-чуть знаком с 1С Предприятием. Так же предполагается, что вы изучали официальное руководство 1С по вопросам OLE DB (часть вторая описани...
  • Visual C++, Как самому сделать plug-in к FAR на Visual C++
    Трудно найти человека, которые не знает или не использует Far - IMHO лучший клон NC для Windows. Кроме того, что это просто очень хороший файл менеджер, к нему есть огромное количество plug-in модулей. Plug-in модуль это DLL-файл, который вместо стандартных Windows функций по работе с монитором, клавиатурой и т.д. обращается к функциям Far-а. Far поддерживает весь набор функций для работы в текстовом режиме. Установка plug-in модуля происходит предельно просто - DLL файл и файлы данных коп...
  • Visual C++, Использование директивы #import в Visual C++
    В данной статье я попытаюсь объяснить то, как работает эта директива и привести несколько примеров её использования. Надеюсь, после этого вы тоже найдёте её полезной.  Директива #import введена в Visual C++, начиная с версии 5.0. Её основное назначение облегчить подключение и использование интерфейсов COM, описание которых реализовано в библиотеках типов....
  • Visual C++, Создание VxD на Visual C++ без ассемблерных модулей
    Виртуальные драйверы устройств (VxD) в Windows во многих случаях являются единственным «честным» способом обхода ограничений, установленных системой для приложений Win32: невозможности прямого доступа к портам ввода-вывода и служебной памяти, эффективной обработки аппаратных прерываний, использования сервисных функций существующих VxD и т.п. Кроме того, без VxD не обходится практически ни один полноценный драйвер физического или виртуального устройства....
  • Visual C++, Основы разработки прикладных виртуальных драйверов
    Как уже отмечалось ранее, виртуальные драйверы служат прежде всего для виртуализации аппаратуры, то есть для предоставления одновременно выполняемым задачам возможности совместного использования устройств компьютера. Измерительная или управляющая аппаратура, подключаемая к компьютеру с целью создания автоматизированной установки, вряд ли будет эксплуатироваться в многозадачном режиме, однако использование для ее управления виртуального драйвера может заметно сократить программные издержки ...