Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поток аля демон 
:(
    Опции темы
Mal Hack
Дата 26.7.2008, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: нет
Всего: 261



Доброе.

Есть приложение, которое должно общаться с девайсами по разным портам. Хочу сделать обращение к каождому порту в отдельном потоке. Т.е. запустить сам поток один раз, а потом в нем выполнять нужные функции по работе с портом. _beginthreadex сразу засовывает функцию на выполнение, что меня не устраивает.

Как я еще могу себе это представить. В поток кидается функция, которая там висит и "ловит" сигналы от ядра приложения: "выполни эту функцию с этими параметрами", ну и посылает сигналы приложению: "функцию выполнил успешно (или ошибкой)". На сколько я понимаю для этой цели необходимо использовать mutex, правда как-то я не совсем понимаю как это работает.

По глупому, если рассуждать, то мне надо все, что находится в определеном namespace выполнять в определенном потоке.

Использовать обертку на Qt не очень хочется в данном случае, ввиду того, что хотелось бы для большей переносимости (приложение должно быть кросплатформенным, понятное дело, что релизация потоков для каждой системы будут различными) оставить на стандартном C++.

Спасибо.
PM ICQ   Вверх
GremlinProg
Дата 26.7.2008, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



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

Событий в модели можно придумать сколь угодно, на каждое событие определить одно конкретное действие (например, событие на чтение конкретного порта, событие на запись в конкретный порт, событие на синхронный вывод результатов, статистики  и т.п.) 

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

для синхронизации данных, заполняемых потоком (синхронный вывод результатов) можно так же использовать события (фидбэк), которые выполняют обратное действие, например: после заполнения исходного массива, демон выставляет такой фидбэк в сигнальное состояние, который в это же время ждет основной поток (приложение), после чего оно может проанализировать информацию, вывести в таблицы, раскрасить кнопочки и т.п.

Я немного упростил, но в целом, фидбэк - это формальный механизм передачи данных как из потока, так и в поток.

завершение демона - то же событие, по активаци которого демон просто прекращает цикл и выходит из своей процедуры потока, предварительно освободив все ранее распределенные данные.

вобщем, практически все манипуляции можно делать на событиях, 

мьютексы и семафоры используются в основном только для разгрузки очереди(дросселирование) или предоставления эксклюзивного доступа к ресурсу, например, когда только один поток должен выполнить ту или иную функцию, в то время как остальные должны ожидать своей очереди.

функции по теме:

CreateEvent - создание сигнального события
SetEvent - активация события
WaitForSingleObject - ожидание объекта синхронизации (напр., события)
WaitForMultiplyObjects - множественное ожидание объектов синхронизации (напр., событий)
CloseHandle - уничтожение события


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Mal Hack
Дата 26.7.2008, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: нет
Всего: 261



В принципе, я себе это так и представлял.
На счет SetEvent's  посмотрю (другие реализации есть, Run-time например). А как подобное в Unix системах реализовывать?

Еще, хотелось бы чтобы сам демон не висел в while(true) а просто ждал сигнала.
PM ICQ   Вверх
Lazin
Дата 26.7.2008, 19:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



можно тупо посылать сообщения потоку через PostThreadMessage, ф в потоке организовать цикл обработки сообщнений 
PM MAIL Skype GTalk   Вверх
chipset
Дата 27.7.2008, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 2
Всего: 165



Цитата(Mal Hack @  26.7.2008,  06:42 Найти цитируемый пост)
По глупому, если рассуждать, то мне надо все, что находится в определеном namespace выполнять в определенном потоке.


Для тривиального случая где надо выполнить все что находится в определенном namespace и пофик на внешнюю информацию.

Код

/* interface */ struct IStep
{
  virtual void Act() = 0;
};
class ThreadableStepIterator
{
 std::vector<IStep*> m_stepArr;

public:

  void AddStep(IStep* step) 
  {
    m_stepArr.push_back(step);
  }

   static DWORD WINAPI Trampoline(LPVOID lpData)
  {
   StepIterator *pThis = reinterpret_cast<StepIterator*>(lpData);

     for(int i = 0; i < pThis->m_stepArr.size(); i++)
      {
        pThis->m_stepArr[i]->Act();
       }

   }
};

};


По сути если представить себе IStep как callback метод то вообще не нужно никаких мьютексов и синхронизации.

В общем ещё можно написать централизованный CallbackManager который будет вызываться после каждого шага в трамплине. Просто непонятно насколько сложно ты хочешь манипулировать с данными в потоке и почему нельзя просто создать тучи потоков последовательно.


Цитата(Mal Hack @  26.7.2008,  06:42 Найти цитируемый пост)
_beginthreadex сразу засовывает функцию на выполнение, что меня не устраивает.


Функция это не простая вещь. Функция может спать сколько угодно и вызывать разные,  в т.ч. нестатические функции через кастинг LPVOID lpParameter.


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Mal Hack
Дата 27.7.2008, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: нет
Всего: 261



Цитата(chipset @  27.7.2008,  09:14 Найти цитируемый пост)
 Просто непонятно насколько сложно ты хочешь манипулировать с данными в потоке и почему нельзя просто создать тучи потоков последовательно.

Тучи потоков, не пройдут, т.к. отправкой команд на устроство должен заниматься один поток, иначе может получиться так, что команда, которая должна выполняться позже придет на устройство раньше. Плюс. Каждая команда взаимосвязана с предыдущей в плане (выполнилась не выполнилась предыдущая, ждать или не ждать выполнения предыдущей команды).

Цитата(chipset @  27.7.2008,  09:14 Найти цитируемый пост)
Функция это не простая вещь. Функция может спать сколько угодно и вызывать разные, 

Это как раз и являтся целью.

Цитата(chipset @  27.7.2008,  09:14 Найти цитируемый пост)
кастинг LPVOID lpParameter.

Это как?
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0571 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.