crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в Доступ к железу в многопоточном приложении
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
 

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
r_13 Дата 18.1.2012, 19:24
  Здесь по классу на девайс и интерфейс тоже есть. Только вместо очередей или сообщений был сделан просто геттер, возвращающий map с идентификаторами и указателями на девайс (интерфейс). Это, видимо, и надо переделать. Всем спасибо.
Iron Bug Дата 18.1.2012, 17:43
 
Цитата(Влад @ 18.1.2012, 12:27) *
Архитектура получилась следующая:

у меня получилось нечто подобное, но только взаимодействие было через очереди, а диспетчер координировал подключение процессов к очередям (там было межпроцессное взаимодействие), выдавая процессам координаты нужной очереди по условному имени девайса.
в общем, вполне нормальная архитектура, если девайсы последовательные. с асинхронными всё намного сложнее.
Влад Дата 18.1.2012, 9:27
  r_13, мне вот как раз несколько (эххх.... изрядно уж!) лет назад приходилось разрабатывать похожую систему..... Несколько (много) "железных" устройств общались с компами по COM-портам и еще взаимодействовали друг с другом при этом.
Архитектура получилась следующая:
- на каждый тип "железного" устройства конструируется свой класс. Все эти "железячные" классы наследуют и поддерживают единый общий интерфейс (наследуются от абстрактного класса). Внутри класса для общения с устройством через COM-порт создаются два потока: на прием и на передачу, и две очереди: принятых сообщений и сообщений на отправку. Класс сам отслеживает таймауты, состояние устройства и прочее....
- количество экземпляров нужного класса определяется количеством железок данного типа, подключенных по каналам связи (у меня читалось из конфиг файла).
- для организации взаимодействия устройств друг с другом сконструирован еще один класс - условно, диспетчер. Диспетчер создает (читая из конфига) нужное число экземпляров конкретных классов.
- взаимодействие экземпляров между собой (как экземпляров одного класса, так и разных классов) идет по схеме "поставщик сообщений - подписчики". Все сообщения, принятые от конкретной железки, экземпляр соответствующего класса отдает диспетчеру. А диспетчер ведет реестр (список, лист) подписчиков, и отдает им сообщения. Здесь получается топология типа "звезда". Подписчик указывает, сообщения какого типа (а они разных типов) он желает получать. Каждый подписчик сам решает, как обрабатывать полученные сообщения. Прямого взаимодействия между железячными экземплярами нет, все идет только и исключительно через диспетчер.
- в одном компе - один диспетчер и несколько "железячных" экземпляров. А диспетчеры разных компов общаются по Ethernet по такой же схеме - на одном компе поднимается "сервер", по сути дела - диспетчер более высокого уровня. Здесь тоже топология "звезда".
Вот как-то так.....
Iron Bug Дата 17.1.2012, 17:55
  для каждой железки делается один поток на всё приложение. он буферизует и отправляет сообщения, а также занимается приёмом. а потом уже асинхронно раздаёт ответы ожидающим.
это единственное нормальное решение при обращении к железу без конкуренции запросов.
r_13 Дата 17.1.2012, 16:09
  Да, так пожалуй безопаснее, хотя одновременный доступ будет только к одной железяке. Впрочем можно и Thread Pool сделать (по одному потоку на железяку) и тогда они между собой общаться смогут. И запросы придется с блокировкой делать, если, скажем надо значение из регистра получить. Для общения с внешними модулями этот вариант наверно стоит попробовать. Но и внутри модуля куча классов, которые получают IHwAccess и работают с ним (доступ к отдельным частям железа и платам расширения). Их запросы через очередь наверно не получится. Иначе придется еще транзакции вводить. Да и таймауты могут появиться.
Влад Дата 17.1.2012, 14:29
  Мне кажется, что это неправильно, что один модуль раздает другим указатели, и эти другие - делают, что хотят и когда хотят..... в том числе, могут обращаться к недоступному больше железу.

Лично я бы сделал бы несколько иначе а врхитектурном плане:
Один модуль ловит сообщения от USB _и_ общается с железом. Он предоставляет всем остальным модулям доступ к железу посредством доступа к _своему интерфейсу_, не предоставляя этим "остальным модулям" прямого доступа к железу. Запросы сторонних модулей могут ставиться в очередь и обрабатываться по логике, определяемой этим "железячным" модулем. Таким образом, все взаимодействие с конкретной USB-железякой инкапсулировано внутри этого модуля. Если железяка отключается, то этот модуль просто завершает все оставшиеся в очереди запросы неуспешно. Нет?
r_13 Дата 17.1.2012, 14:10
  Добрый день,
есть многомодульная программа с кучей потоков (threads) и есть железо, которое подключается по USB. Один из модулей ловит сообщения от USB и создает\удаляет объекты класса Device, который предоставляет доступ к железу. Куча других классов из разных модулей получает указатели на объекты этого класса по запросу и манипулируют с ними. Если происходит USB disconnect, то модуль, что раздает указатели на Device, посылает соответствующее сообщение. Но поскольку система многопоточная, то сообщение может прийти позже, чем будет попытка обращения к недоступному более железу.
Ясно, что надо синхронизировать через mutex (что и делается), но количество объектов, желающих общаться с железом растет и учесть все варианты становится все сложнее. Может есть какой-нибудь design pattern для этого? Может это не правильно раздавать всем подряд указатели? Нужен какой-нибудь режим регистрации тех, кто получает указатель? Задача то довольно стандартная для околожелезячных прог. Наверняка есть "стандартное" решение\подход...
Просмотр темы полностью (откроется в новом окне)
RSS Текстовая версия Сейчас: 29.3.2024, 16:48