реклама на сайте
подробности

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Альтернативный вариант задания функции процесса
ArtDenis
сообщение Nov 10 2012, 13:36
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Приветствую.

Начал смотреть scmRTOS. Сразу начал резать глаз способ реализации функции процесса:
Код
typedef OS::process<OS::pr0, 300> TProc1;

namespace OS
{
    template <>
    OS_PROCESS void TProc1::exec()
    {
        for(;;)
        {
            ef.wait();
            PB0.Off();
        }
    }
}

Необходимость реализовывать функцию процесса внутри поля имён OS, а добавление template <> вызывает некоторое удивление wacko.gif

Подумалось, почему-бы не сделать ф-цию exec просто ф-цией своего собственного класса? На скорую руку сделал несколько изменений в исходниках scmRTOS и весь код декларации и реализации процесса превратился в:

Код
class TProc1 : public OS::process<TProc1, OS::pr0, 300>
{
public:
    static void exec()
    {
        for(;;)
        {
            ef.wait();
            PB0.Off();
        }
    }
};


Что мы в итоге имеем? 1) Класс, в котором можно инкапсулировать данные и методы процесса. Закрытые и используемые только в TProc1 данные можно объявить в секции private класса и никто к ним не получит доступ. 2) Более привычный способ реализации ф-ции.

Кто что думает на этот счёт?


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 10 2012, 15:59
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(ArtDenis @ Nov 10 2012, 19:36) *
Что мы в итоге имеем? 1) Класс, в котором можно инкапсулировать данные и методы процесса. Закрытые и используемые только в TProc1 данные можно объявить в секции private класса и никто к ним не получит доступ. 2) Более привычный способ реализации ф-ции.

Кто что думает на этот счёт?

Во! Я всегда мечтал, чтоб можно было того, инкапсулироватьsm.gif
Вопрос только такой: какие изменения были внесены в саму ось, и как это отразилось на размере кода/быстродействии/размере ОЗУ?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Nov 10 2012, 16:10
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



AHTOXA, по идее вообще никак не должно влиять на быстродействие и потребление памяти, т.к. реально дополнительный исполняемый код вообще не добавляется по сравнению с оригинальной версией. Это просто другой способ определить функцию процесса.

Выкладываю доработанные файлы в архиве.
Прикрепленные файлы
Прикрепленный файл  Common.zip ( 6.92 килобайт ) Кол-во скачиваний: 39
 


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 10 2012, 16:31
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Ну что я могу сказать... Мне очень понравилось. Это именно то, о чём так долго говорили большевики мы с ReAl'ом sm.gif
Проблема только в потере совместимости со всеми существующими проектами.
Будет интересно услышать, что скажут остальные участники.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Nov 11 2012, 03:21
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (ArtDenis @ Nov 10 2012, 20:36) *
Необходимость реализовывать функцию процесса внутри поля имён OS,

Откуда взяли, что это необходимость? Не помню, чтобы у меня где-то прикладные процессы жили в пространстве имён OS.

QUOTE (ArtDenis @ Nov 10 2012, 20:36) *
а добавление template <> вызывает некоторое удивление wacko.gif

Откуда удивление? Это стандартное требование языка С++ - если не указана общая (generic) реализация, будьте добры предоставить специализацию, которую необходимо обозначить в соответсвии с требованиями языка. Функция exeс и является полной специализацией.

QUOTE (ArtDenis @ Nov 10 2012, 20:36) *
Подумалось, почему-бы не сделать ф-цию exec просто ф-цией своего собственного класса? На скорую руку сделал несколько изменений в исходниках scmRTOS и весь код декларации и реализации процесса превратился в:

Т.е. в итоге вместо одного template<> нужно создавать каждый раз целый класс. Сомнительне преимущество. Что касается инкапсуляции, то этот принцип можно реализовать и на текущем варианте, только использовав отношение включения вместо отношения наследования, как это сделано у вас.

QUOTE (AHTOXA @ Nov 10 2012, 22:59) *
Во! Я всегда мечтал, чтоб можно было того, инкапсулироватьsm.gif

Уже обсуждали мы это. Что мешает тебе инкапсулировать, написав обёртку вокруг процесса? В данном случае я вижу появление лишней сущности. Их и так там две - TBaseProcess и process<>, но это сделано из соображений эффективности реализации. А третья добавляется только из синтаксических предпочтений.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Nov 11 2012, 05:00
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(dxp @ Nov 11 2012, 09:21) *
Откуда взяли, что это необходимость? Не помню, чтобы у меня где-то прикладные процессы жили в пространстве имён OS.

А как тогда можно сделать без реализации функции процесса внутри namespace OS ? Я просто пока что судил по примерам, которые идут с scmRTOS.

Цитата(dxp @ Nov 11 2012, 09:21) *
Откуда удивление? Это стандартное требование языка С++ - если не указана общая (generic) реализация, будьте добры предоставить специализацию, которую необходимо обозначить в соответсвии с требованиями языка. Функция exeс и является полной специализацией.

Я могу ошибаться, но считается, что уровень познаний в языке программиста который использует библиотеку, обычно меньше, чем уровень знаний того, кто эту библиотеку пишет. Поэтому библиотека может быть сложной внутри, но её использование должно быть простым и понятным. Лично я видел очень небольшое количество С++ библиотек, которые бы заставляли программиста писать специализацию вот таким вот образом, да и то это приходилось делать в очень исключительных случаях. Поэтому и вызывает удивление, что практически базовая функциональность реализована через требование специализации шаблонной функции, которая вызывается библиотекой.

Цитата(dxp @ Nov 11 2012, 09:21) *
Т.е. в итоге вместо одного template<> нужно создавать каждый раз целый класс. Сомнительне преимущество.

Да, именно класс. И в этом преимущество, т.к. класс в с++ - это более универсальная вещь, чем функция.

Цитата(dxp @ Nov 11 2012, 09:21) *
Что касается инкапсуляции, то этот принцип можно реализовать и на текущем варианте, только использовав отношение включения вместо отношения наследования, как это сделано у вас.

Можно пример? Просто я не представляю как это можно сделать без лишних телодвижений.


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 11 2012, 06:07
Сообщение #7


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Nov 11 2012, 09:21) *
Уже обсуждали мы это. Что мешает тебе инкапсулировать, написав обёртку вокруг процесса? В данном случае я вижу появление лишней сущности. Их и так там две - TBaseProcess и process<>, но это сделано из соображений эффективности реализации. А третья добавляется только из синтаксических предпочтений.

Да, обсуждали. В тот раз я не смог тебя убедитьsm.gif
Но тогда раз предложенное мной решение было связано с дополнительными расходами. А это решение - не влечёт никаких доп. расходов.
Зачем писать обёртку, если можно инкапсулировать всё прямо в классе процесса? Вот как раз-таки обёртка - это лишняя сушность.
Существующий подход позволяет пользователю специализировать только функцию exec(). А предложенный - позволяет полноценно наследовать класс процесса. Какой вариант гибче?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Nov 11 2012, 12:02
Сообщение #8


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (ArtDenis @ Nov 11 2012, 12:00) *
А как тогда можно сделать без реализации функции процесса внутри namespace OS ? Я просто пока что судил по примерам, которые идут с scmRTOS.

Я не знаю, какие примеры вы смотрели, в моих примерах этого нет и никогда не было, мне даже в голову не приходило помещать функцию процесса в пространство имён OS - ведь функция процесса - это уже прикладной код, а не код ОС. Исключение составляет фоновый процесс Idle, он целиком помещён в пространство имён OS.

QUOTE (ArtDenis @ Nov 11 2012, 12:00) *
Я могу ошибаться, но считается, что уровень познаний в языке программиста который использует библиотеку, обычно меньше, чем уровень знаний того, кто эту библиотеку пишет. Поэтому библиотека может быть сложной внутри, но её использование должно быть простым и понятным. Лично я видел очень небольшое количество С++ библиотек, которые бы заставляли программиста писать специализацию вот таким вот образом, да и то это приходилось делать в очень исключительных случаях. Поэтому и вызывает удивление, что практически базовая функциональность реализована через требование специализации шаблонной функции, которая вызывается библиотекой.

Всё правильно, так и есть. И насколько мне известно, scmRTOS использует много людей, которые в плюсах не особенно подготовлены (а немало из них не особенно и стремится постичь глубины С++), им вполне достаточно знать базовый синтаксис использования, основное из которого - это обращение <ObjectName.MemberName>. И уж написать один раз перед функций template<> никакого труда не составляет, при этом совершенно нет необходимости напрягаться по поводу специализаций и прочего.

Вы же предлагаете вариант с созданием класса да ещё и не самым тривиальным способом (наследование от шаблона по методу стратегии), тут у пользователя, который писал, пишет и собирается продолжать писать в С-стиле, вопросов возникнет куда больше - ему придётся врубаться в синтаксис определения классов и наследования, создавать свои определения классов и т.д. - словом, писать свой код в С++ стиле по полной программе. Это совсем не то же самое, что просто создать определение функции по образцу и использовать её в привычном С-стиле. Вас смущает слово template<>? А слово OS_PROCESS, которое используются там же, вас не смущает?

QUOTE (ArtDenis @ Nov 11 2012, 12:00) *
Да, именно класс. И в этом преимущество, т.к. класс в с++ - это более универсальная вещь, чем функция.

А если в ряде случаев эта универсальность не нужна? Тогда накладяки на пустом месте. Процесс должен предоставлять отдельный асинхронный поток управления, он это делает - предоставляет функцию exec. Больше он ничего не должен. Зачем его нагружать в базовом исполнении, мотивируя гипотетическими фичами? Лишнее это. База есть. Если кому мало - вэлком, можно расширять.

QUOTE (ArtDenis @ Nov 11 2012, 12:00) *
Можно пример? Просто я не представляю как это можно сделать без лишних телодвижений.

Очень просто. Если вам или кому-либо ещё хочется иметь функциональность процесса инакпсулиированной в объекте, определите этот объект, сделайте его "процессную" функцию встраиваемой (чтобы вызова не было) и вызывайте её из process<>::exec(). Всё.

Существующий подход предоставляет бОльшую гикость и простоту. Можно сделать так, а можно эдак. Далее, по проектированию. Хороший стиль проектирования подразумевает: "одна сущность - один класс". Один процесс очень часто участвует в реализации далеко не одной сущности, поэтому запихивание всех реализаций в один класс процесса выглядит просто данью парадигме программирования. Вышеописанный способ (определение класса и вызов его "процессной" функии из функции процесса) свободен от этого недостатка - можно создать несколько классов этим способом и вызывать их функции из exec. Инкапсуляция на месте, искусственных "привязок" "класс-процесс" нет.

QUOTE (AHTOXA @ Nov 11 2012, 13:07) *
Да, обсуждали. В тот раз я не смог тебя убедитьsm.gif

Приводимыми агрументами и не удастся. sm.gif Контрагументы, имхо, сильнее.

QUOTE (AHTOXA @ Nov 11 2012, 13:07) *
Зачем писать обёртку, если можно инкапсулировать всё прямо в классе процесса? Вот как раз-таки обёртка - это лишняя сушность.

Не более лишняя, чем определение класса в предлагаемом варианте. Скажи, чем отношение наследования лучше отношения включения? В данном конкретном случае. Чем хуже, уже говорилось: в текущем варианте можно юзать функцию процесса, как есть, в С-стиле, можно включить в другой класса, причём двумя способами - отнаследовашись от process<> или вызывая из process<>::exec() функции других классов, которые реализуют принципы инкапсуляции и абстракции, в то время, как предлагаемый вариант предоставляет только один способ - безальтернативно включить весь код процесса в один класс.

QUOTE (AHTOXA @ Nov 11 2012, 13:07) *
Существующий подход позволяет пользователю специализировать только функцию exec(). А предложенный - позволяет полноценно наследовать класс процесса. Какой вариант гибче?

Что мешает тебе наследовать от process<>? Хотя я бы так не делал - лучше написать отдельный класс и вызывать его функцию (или функции) из exec.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Nov 11 2012, 12:43
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(dxp @ Nov 11 2012, 18:02) *
Я не знаю, какие примеры вы смотрели, в моих примерах этого нет и никогда не было, мне даже в голову не приходило помещать функцию процесса в пространство имён OS - ведь функция процесса - это уже прикладной код, а не код ОС

Я смотрел примеры AVR и Cortex3 для GCC. Там везде ф-ция процесса реализована в namespace OS.

Сообщение отредактировал ArtDenis - Nov 11 2012, 12:43


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
dxp
сообщение Nov 11 2012, 13:00
Сообщение #10


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (ArtDenis @ Nov 11 2012, 19:43) *
Я смотрел примеры AVR и Cortex3 для GCC. Там везде ф-ция процесса реализована в namespace OS.

Помещать функцию в пространство имён или не помещать - это личное предпочтение автора примера, ни язык, ни ОС этого не требуют. В других примерах - тот же AVR/IAR, в частности, этого нет.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 11 2012, 16:00
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Nov 11 2012, 19:00) *
Помещать функцию в пространство имён или не помещать - это личное предпочтение автора примера, ни язык, ни ОС этого не требуют. В других примерах - тот же AVR/IAR, в частности, этого нет.

Вообще-то она изначально туда помещена, в объявлении. То, что некоторые компиляторы до сих пор позволяют не указывать это в реализации, не выносит exec() из пространства имён OS.

Цитата(dxp @ Nov 11 2012, 18:02) *
Приводимыми агрументами и не удастся. sm.gif Контрагументы, имхо, сильнее.

Или же кто-то просто упёрсяsm.gif

Цитата(dxp @ Nov 11 2012, 18:02) *
Не более лишняя, чем определение класса в предлагаемом варианте. Скажи, чем отношение наследования лучше отношения включения? В данном конкретном случае.

А где ты видишь здесь включение? Никакого включения нет. Есть вызов некой функции некоего стороннего объекта из функции exec() другого класса. Какое же это включение?
Цитата(dxp @ Nov 11 2012, 18:02) *
предлагаемый вариант предоставляет только один способ - безальтернативно включить весь код процесса в один класс.

Опять не так. Что мешает включить какой-то другой объект в класс процесса? Или же, по-нынешнему, вызвать из exec() функции любого другого объекта?
Короче, сплошные профиты от нынешнего варианта. А недостатков я по-прежнему не вижуsm.gif
Цитата(dxp @ Nov 11 2012, 18:02) *
Что мешает тебе наследовать от process<>? Хотя я бы так не делал - лучше написать отдельный класс и вызывать его функцию (или функции) из exec.

Не помню, но что-то вроде мешает. Не получается, емнимс. Хотя надо попробовать...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 11 2012, 19:15
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Йоу! Я придумал, как совместить эти два варианта 08.gif

Короче, переименовываем в новом варианте process в customProcess, а process объявляем вот так:
Код
        template<TPriority pr, size_t stack_size>
        class process : public customProcess<process<pr, stack_size>, pr, stack_size>
        {
        public:
            OS_PROCESS static void exec();
        };

И всё! Старый вариант работает, и новый (наследование от customProcess) - тоже.
Получается вообще замечательно: старые проекты все подхватятся без изменений, а в новых пользователь имеет возможность выбрать для себя более удобный вариант. yeah.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Nov 11 2012, 20:07
Сообщение #13


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(ArtDenis @ Nov 11 2012, 07:00) *
Лично я видел очень небольшое количество С++ библиотек, которые бы заставляли программиста писать специализацию вот таким вот образом, да и то это приходилось делать в очень исключительных случаях.
Старые версии компиляторов могли пропускать, но если нужно сделать свою специализацию шаблона, то иначе по стандарту нельзя.

Цитата(AHTOXA @ Nov 10 2012, 18:31) *
Ну что я могу сказать... Мне очень понравилось. Это именно то, о чём так долго говорили большевики мы с ReAl'ом sm.gif
Да-да-да.

Цитата(AHTOXA @ Nov 10 2012, 18:31) *
Проблема только в потере совместимости со всеми существующими проектами.
Будет интересно услышать, что скажут остальные участники.
Вот потому и я вчера промолчал. Кроме «наконец свершилось» всё равно ничего в голову не лезло :-)

Цитата(AHTOXA @ Nov 11 2012, 18:00) *
Вообще-то она изначально туда помещена, в объявлении. То, что некоторые компиляторы до сих пор позволяют не указывать это в реализации, не выносит exec() из пространства имён OS.
Собственно, оно и в примерах появилось в ответ на ругань более свежих версий компиляторов.


Цитата(AHTOXA @ Nov 11 2012, 21:15) *
Йоу! Я придумал, как совместить эти два варианта 08.gif
Да, похоже, так лучше.
Я уж начал было думать про просто параллельное существование нынешнего process и нового. Но это плохо, по сути одно и то же и при модификациях требовало бы менять в двух местах.


Цитата(AHTOXA @ Nov 11 2012, 18:00) *
Не помню, но что-то вроде мешает. Не получается, емнимс.
Exec() в этом унаследованном от шаблона получается другой (перегруженный). А шаблон хочет затолкать куда надо адрес своего, который остается неопределённым.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Nov 12 2012, 02:41
Сообщение #14


Частый гость
**

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(AHTOXA @ Nov 12 2012, 01:15) *
Йоу! Я придумал, как совместить эти два варианта 08.gif

Да, удачное решение sm.gif Мне оно в голову не пришло


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 12 2012, 07:13
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (AHTOXA @ Nov 11 2012, 21:15) *
Я придумал, как совместить эти два варианта
Выглядит слабочитаемо. Что мешает завести свой потомок TBaseProcess вне пространства имен OS, оставив в покое родной шаблон?

QUOTE (ArtDenis @ Nov 10 2012, 15:36) *
CODE
class TProc1 : public OS::process<TProc1, OS::pr0, 300>
Тут TProc1 передается как параметр шаблона только для того, чтобы в конструкторе взять адрес его exec. Страдает мое чувство прекрасного. Возможно менее разрушительным будет добавить второй конструктор, который получает адрес exec в качестве параметра? Или сделать этот конструктор с параметром единственным, задав ему значение по умолчанию? А в потомке вызывать с адресом своего exec. Тоже некрасиво - забудешь в потомке описать такой конструктор и компилятор не отловит. Не знаю. Хотя отловит - линкер выругается, что не определен exec() в предке... Но такое сообщение неверно описывает причину ошибки.

Как вариант - можно добавить обсуждаемую фичу в Extensions. Именно как отдельного наследника TBaseProcess.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th April 2024 - 06:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01559 секунд с 7
ELECTRONIX ©2004-2016