|
Использование очереди сообщений |
|
|
|
Nov 27 2009, 08:25
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Здравствуйте. Помогите пожалуйста разобраться с использованием очереди сообщений. У меня есть процесс (A), периодически передающий пакеты по UART. Второй процесс (  может в произвольные моменты требовать от него передачи пакетов, определяемых пользователем. Для этого я собираюсь использовать очередь сообщений. Но ведь в очередь заносится только указатель на пакет, а как быть с самими данными, особенно если пришло несколько запросов подряд? Правильно ли я понимаю, что мне необходимо помимо очереди создать что-то вроде кольцевого буфера и обернуть функции POST и PEND для очереди сообщений в свои функции, которые будут брать/класть указатель из/в очереди, извлекать данные из буфера и обслуживать указатели этого буфера? Спасибо. PS. Пока писал сообщение, в голову пришла ещё одна мысль - процесс B динамически выделяет память, а процесс A после вычитывания сообщения её освобождает.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Nov 27 2009, 08:45
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Dima_G @ Nov 27 2009, 11:32)  Все зависит от того - что подразумеватеся под элементом очереди. Если буфер (+указатель на следующий элемент), то дополнительного пула не нужно))))
Динамически выделять / освобождать память не сильно хорошая идея в embedded системах В большинстве осей, в той же uC/OS в очереди хранятся именно указатели. А по второму замечанию - полностью согласен. Потому, наверное, эта идея пришла только в самый последний момент (как самая негодная)
Сообщение отредактировал Harvester - Nov 27 2009, 08:47
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Nov 27 2009, 08:53
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(Harvester @ Nov 27 2009, 12:45)  В большинстве осей, в той же uC/OS в очереди хранятся именно указатели. Ну а что мешает сделать свою очередь? Ни либо на указателях я бы делал так: хранил отдельно пул буферов Создал бы очередь - обозвал бы ее FreeQueue Создал бы очередь в драйвере - назвал TxQueue; Далее - приложение берет из очереди FreeQueue указатель (считай - буфер), заполняет буфер и помещает указатель на него в TxQueue Драйвер обнаруживет в TxQueue пакет, обрабатывает его (передает), и помещает в FreeQueue как-то так
|
|
|
|
|
Nov 27 2009, 11:38
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(Dima_G @ Nov 27 2009, 11:53)  Ну а что мешает сделать свою очередь? Ни либо на указателях я бы делал так: хранил отдельно пул буферов Создал бы очередь - обозвал бы ее FreeQueue Создал бы очередь в драйвере - назвал TxQueue; Далее - приложение берет из очереди FreeQueue указатель (считай - буфер), заполняет буфер и помещает указатель на него в TxQueue Драйвер обнаруживет в TxQueue пакет, обрабатывает его (передает), и помещает в FreeQueue как-то так  А ведь так можно вообще обойтись без очереди - использовать пул буферов и счётный семафор!
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Nov 27 2009, 11:59
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Harvester @ Nov 27 2009, 14:38)  А ведь так можно вообще обойтись без очереди - использовать пул буферов и счётный семафор! Нафига организовывать очередь руками из дополнительного буфера и семафора, если их поддержка УЖЕ ЕСТЬ в системе. Если очередь можно пользовать только для указателей, то нужно только добавить к ней один буфер и все. Цитата(Harvester @ Nov 27 2009, 11:45)  В большинстве осей, в той же uC/OS в очереди хранятся именно указатели. В большинстве - хранится все, что хочется. Вопрос только в допустимости накладных расходов. Если функций работы с очередью позволяют прямой доступ к буферу очереди, без копирования тела сообщений, то это уже без чрезмерных затрат позволяет действительно гонять через очередь и данные. Цитата(Dima_G @ Nov 27 2009, 11:32)  Динамически выделять / освобождать память не сильно хорошая идея в embedded системах Зависит от менеджера памяти, нагрузки и необходимости экономии ресурсов. В большинстве случаев организация буферизации через динамически выделяемые блоки на одно сообщение, действительно, чрезмерно заумна.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 27 2009, 12:23
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Nov 27 2009, 15:59)  Нафига организовывать очередь руками из дополнительного буфера и семафора, если их поддержка УЖЕ ЕСТЬ в системе. Если очередь можно пользовать только для указателей, то нужно только добавить к ней один буфер и все. Под буфером, Вы имеете в виду - циклический буфер? Мне большей частью удобнее НЕ использовать системные очереди. Исключительно из-за их "сишной" природы, как следствие - потери информации о типе вложенного объекта
|
|
|
|
|
Nov 27 2009, 12:47
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(zltigo @ Nov 27 2009, 14:59)  Нафига организовывать очередь руками из дополнительного буфера и семафора, если их поддержка УЖЕ ЕСТЬ в системе. Вообще-то это не я придумал. Это написал Лабросс в книге по uC/OS, как пример использования счетного семафора. Цитата(zltigo @ Nov 27 2009, 14:59)  Если очередь можно пользовать только для указателей, то нужно только добавить к ней один буфер и все. Действительно, как-то сразу не подумал. Ведь ядро уже контролирует заполненность очереди. И если очередь не полна, значит, как минимум, одно из самых ранних сообщение уже вычитано и отправитель может писать данные в очередную секцию кольцевого буфера. Это действительно проще связного списка. Спасибо!
Сообщение отредактировал Harvester - Nov 27 2009, 12:47
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Nov 27 2009, 13:03
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Dima_G @ Nov 27 2009, 15:23)  Под буфером, Вы имеете в виду - циклический буфер? Совершенно не имеет значения какой - любой, какой оптимален для данного типа данных, нагрузки и прочего. Довольно часто очень просто и удобно реализуются линейные под фрейм расположенные внутри кольцевого. А если фреймы фиксированной длинны, то сам бог велел так делать - 0 недостатков. Цитата Мне большей частью удобнее НЕ использовать системные очереди. Исключительно из-за их "сишной" природы, как следствие - потери информации о типе вложенного объекта Еруда полная, а не причина, либо тип фиксирован, либо Вы его по любому будете восстанавливать по, например, заголовку. Цитата(Harvester @ Nov 27 2009, 15:47)  И если очередь не полна,значит, как минимум, одно из самых ранних сообщение уже вычитано и отправитель может писать данные в очередную секцию кольцевого буфера. И если полна, то тоже может, ибо должны быть ДВА указателя - на чтение, который проходит через очередь до процесса передачи читающий из буфера передачи и отдельно болтающийся указатель на запись, по которому вне зависимости (ну кроме контроля за фатальным переполнением) от наличия в буфере непереданных фреймов осуществляется запись.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 27 2009, 13:41
|
Местный
  
Группа: Участник
Сообщений: 338
Регистрация: 1-02-06
Из: Королев, М.О.
Пользователь №: 13 846

|
Цитата(zltigo @ Nov 27 2009, 16:03)  И если полна, то тоже может, ибо должны быть ДВА указателя - на чтение, который проходит через очередь до процесса передачи читающий из буфера передачи и отдельно болтающийся указатель на запись, по которому вне зависимости (ну кроме контроля за фатальным переполнением) от наличия в буфере непереданных фреймов осуществляется запись. Что-то теперь я совсем запутался.  Как может указатель на запись"отдельно болтаться", если именно его необходимо класть в очередь после заполнения фрейма буфера. И потом, если уж мы используем два указателя, т.е. организуем кольцевой буфер, то какой смысл в очереди? Проще ведь будет использовать счетный семафор, да и по ресурсам выгоднее.
--------------------
-Да как так-то?/-Да как-то так/-Ну так-то да
|
|
|
|
|
Nov 27 2009, 14:57
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Nov 27 2009, 16:03)  Еруда полная, а не причина, либо тип фиксирован, либо Вы его по любому будете восстанавливать по, например, заголовку. Реализации универсальных сишных очередей, которые я видел - обычно работают с void указателем на элемент: Код push(void* pObj_); void* pop(); соответственно, никто не застрахован от ошибок В С++ можно использовать такой подход Цитата template <class ELEMENT>\ class TClQueue { push(ELEMENT* pclEl_); ELEMENT* pop();
}; В эту очередь получится запихать либо ELEMENT, либо производные от него
|
|
|
|
|
Nov 27 2009, 15:12
|
.NET developer
  
Группа: Свой
Сообщений: 218
Регистрация: 20-10-07
Из: Новосибирск
Пользователь №: 31 532

|
Цитата Динамически выделять / освобождать память не сильно хорошая идея в embedded системах а можно аргументировать? сам применяю new/delete и пытаюсь понять - будут грабли или нет.
|
|
|
|
|
Nov 27 2009, 15:42
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Harvester @ Nov 27 2009, 16:41)  Что-то теперь я совсем запутался.  Как может указатель на запись"отдельно болтаться", если именно его необходимо класть в очередь после заполнения фрейма буфера. Вопросы кто чем для кого является  возможен взгляд с разных сторон  . В очередь кладется указатель чтения - по нему процесс передачи читает из буфера, то, что он будет передавать  . Указатель записи это принадлежность функции, которая заполняет буфер передачи - по нему будет занесен фрейм и его значение до занесения фрейма будет помещено в очередь. Цитата И потом, если уж мы используем два указателя, т.е. организуем кольцевой буфер, то какой смысл в очереди? Проще ведь будет использовать счетный семафор, да и по ресурсам выгоднее. То, что Вы пытаетесь описать, вообще буфера не требует  , поскольку Вы упорно предполагаете, что в кольцевом буфере по определению рассчитанном на МНОГО фреймов лежит ОДИН. Для одного нужен ОДИН указатель - нет вопросов. Если Мы действительно используем кольцевой буфер, как буфер, а не лишнюю приблуду, то в нем могут лежать МНОГО фреймов, для них нужно МНОГО указателей. Эти указатели и лежат в очереди до того момента, когда процесс передачи извлечет очередной и начнет по нему вытаскивать из буфера информацию. Цитата(Dima_G @ Nov 27 2009, 17:57)  соответственно, никто не застрахован от ошибок Поверье мне, что ошибок Вы и так наделаете. Цитата В С++ можно использовать такой подход Ненужные выкрутасы на ровном месте для ЧАСТНОГО случая. Ничего, кроме лишнего разнообразия в решении не дает.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Nov 27 2009, 16:11
|
Местный
  
Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699

|
Цитата(zltigo @ Nov 27 2009, 18:42)  Поверье мне, что ошибок Вы и так наделаете.
Ненужные выкрутасы на ровном месте для ЧАСТНОГО случая. Ничего, кроме лишнего разнообразия в решении не дает. Это я уже обсуждать не буду, а то тема сведется к холивару С vs С++. Остановимся на том, что почему-то мне так удобнее  Цитата(Andron_ @ Nov 27 2009, 19:12)  а можно аргументировать? сам применяю new/delete и пытаюсь понять - будут грабли или нет. Можно столкнуться с фрагментацией памяти Ненормированное время выделения памяти Нереентерабельность выделения памяти Ну и мое ИМХО - при статическом распределении ресурсов система более предсказуема  вот, почитайте - зедсь есть немного про это http://www.embedded.com/story/OEG20020222S0026
Сообщение отредактировал Dima_G - Nov 27 2009, 16:15
|
|
|
|
|
Nov 27 2009, 16:49
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Dima_G @ Nov 27 2009, 19:11)  Это я уже обсуждать не буду, а то тема сведется к холивару С vs С++. Остановимся на том, что почему-то мне так удобнее  C++ тут АБСОЛЮТНО ни причем - на любом языке можете наваять оберток не имеющих никакого смысла и главное годящихся только для частного случая. Изобразить, например, "специальную очередь" для какого-либо фрейма можно по любому, только кроме лишнего исходного текста и лишних сущностей такие выкрутасы не дают ничего. Цитата(Dima_G @ Nov 27 2009, 19:11)  Можно столкнуться с фрагментацией памяти А можно и нет, если принять меры. Цитата Ненормированное время выделения памяти Ну не надо использовать, например, линукс с файлами подкачки и прочим. Хотя именно в том-же линуксе драйвера делают и много много более мрачные системные вызовы  Цитата Нереентерабельность выделения памяти Ну это если совсем без головы на плечах. Цитата Ну и мое ИМХО - при статическом распределении ресурсов система более предсказуема  Эх, конечно. Только вот если с ресурсами напряг и всем нарезать их про запас не хватает?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|