Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Multithreading + MFC, Нужен совет 
V
    Опции темы
deniska
Дата 30.6.2006, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



Задача такая. Помимо потока GUI необходимо создать еще один, который 10 раз в сек опрашивает железку, и некоторые результаты должен вносить в контролы формы ( несколько Edit, несколько CheckBox, рисование на Bitmapе ). Как такие вещи обычно реализовываются?
 ( Если по MSDN то это что? user-interface thread или working thread? ), какие параметры нужно передать в функцию потока. структуру из хэндлов? вроде криво как-то. вобщем need help smile 


Был бы очень благодарен за маленький кусок кода в котором в отдельном потоке в Edit вставляются числа от Random или ченить в этом роде. 
PM MAIL ICQ   Вверх
deniska
Дата 30.6.2006, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



 smile  smile  smile 
ну хоть кто-нибудь, помогите разобраться 
PM MAIL ICQ   Вверх
Earnest
Дата 30.6.2006, 07:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Не стОит обращаться к окнам, созданным в другом потоке, чтобы прямо туда что-то записывать. Лучше реализовать так: пусть твой поток опрашивает железку и меняет состояние (заносит данные) в некий объект, независимо от GUI. А GUI на idle опрашивает этот объект и, если были изменения, изменяет значение полей. Конечно, доступ к данным объекта нужно защитить хотя бы critical section.
Я недавно в одной из тем приводила код пары простых классов, реализующих синхронизацию on-idle. Поищи слово CStampTracker.
Опрос on-idle можно делать, в зависимости от типа окна, на WM_IDLEUPDATECMDUI (для немодальных окон) или на WM_KICKIDLE (для модальных).
Примерно так:

Код

// класс, в котором храняться данные (см. тему с кодом CStampTracker)
// к объекту этого класса должен иметь доступ поток и GUI
class CMyData: public CStampHolder 
{
public:
   int getData() const
   {
       CSingleLock _lock(&m_cs,TRUE);
       return m_data;
   }
   void setData(int data)
   {
       CSingleLock _lock(&m_cs,TRUE);
       m_data = data;
       Modified();
   }

private:
   int m_data;
   mutable CCriticalSection m_cs;
}; 

// окно в главном потоке
class CMyWindow: public CDialog  
{
public:
   ...
   afx_msg void OnIdleUpdate()
   {
      if (m_Tracker.EnsureSync (*m_pData))
      {
          CString str;
          str.Format (_T("%d"), m_pData->getData());
          m_edit.SetWindowText(str);
      }
   }

private:
   CStampTracker m_tracker;
   CEdit m_edit;
   CMyData* m_pData;
};

BEGIN_MESSAGE_MAP(...)
   // или WM_KICKIDLE, если окно модальное
   ON_MESSAGE_VOID (WM_IDLEUPDATECMDUI, OnIdleUpdate)
END_MESSAGE_MAP()
 


--------------------
...
PM   Вверх
deniska
Дата 30.6.2006, 08:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



Цитата

Конечно, доступ к данным объекта нужно защитить хотя бы critical section.


А зачем? я всегда думал что если один поток ТОЛЬКО записывает данные в некую структуру например, а второй ТОЛЬКО считывает их оттуда, то синхронизация не нужна. Я не прав? 
PM MAIL ICQ   Вверх
takedo
Дата 30.6.2006, 08:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



По моему обработка в OnIddle излишня. Можно просто менять данные и после этого посылать сообщение. При этом синхронизировать нужно только обращение к данным. smile

Добавлено @ 08:05 
deniska, ты не прав

Добавлено @ 08:06 
потоки считай выполняются параллельно(это не так, но в общем предполагать нужно именно так). Если один поток начал писать данные(5 бит), а второй их в этот момент считывает, что получит второй? - ерудну 


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
takedo
Дата 30.6.2006, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Earnest, прошу прощения, но "mutable CCriticalSection m_cs;" - что значит mutable?

 


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
Earnest
Дата 30.6.2006, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(deniska @  30.6.2006,  09:01 Найти цитируемый пост)
А зачем? я всегда думал что если один поток ТОЛЬКО записывает данные в некую структуру например, а второй ТОЛЬКО считывает их оттуда, то синхронизация не нужна. 

Takedo, в общем, правильно сказал. Только насчет 5 бит погорячился. Все-таки существует некоторая атомарность. Если речь идет об интах, то можно обойтись функциями Interlocked... Но я ведь просто пример привела - данные обычно более сложные. 

Цитата(takedo @  30.6.2006,  09:04 Найти цитируемый пост)
По моему обработка в OnIddle излишня

Нет, она позволяет избавить поток, опрашивающий железку, от ненужных связей и зависимостей. Кроме того, а что если слушателей будет больше, т.е. за данными нужно следать 2 и более окнам или другим объектам? Описанный механизм синхронизации позволяет это сделать, не внося изменений в основной код.

Цитата(takedo @  30.6.2006,  09:25 Найти цитируемый пост)
что значит mutable

Ну, takedo, не ожидала от тебя такого вопроса.  smile 
mutable позволяет изменять переменную в не-константных функциях. См. getData: CSingleLock хочет неконстантную ссылку, а функция - константная.
 


--------------------
...
PM   Вверх
takedo
Дата 30.6.2006, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Earnest
Цитата

Нет, она позволяет избавить поток, опрашивающий железку, от ненужных связей и зависимостей. Кроме того, а что если слушателей будет больше, т.е. за данными нужно следать 2 и более окнам или другим объектам? Описанный механизм синхронизации позволяет это сделать, не внося изменений в основной код.
 - очень разумно. Только иногда можно ведь в OnIddle и вообще не попасть? smile . Если такое произойдет(это я для тебя )
deniska, стараюсь smile ) можно поставить в каждом окне таймер и по нему вести обновление. Вообщем решать тебе. вот можешь тут посмотреть, глядишь поможет чем http://forum.vingrad.ru/index.php?showtopic=100331. И поищи по форму - тут оказывается в факе можно на интересные вещи наткнуться smile

Добавлено @ 08:48 
Цитата
Ну, takedo, не ожидала от тебя такого вопроса.   
 не сердись, я же подписываюсь: "я не гольфист - я хоккеист" smile  


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
deniska
Дата 30.6.2006, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



WM_IDLEUPDATECMDUI undeclared identifier.
MSDN - тишина.
че это за зверь такой? какое-то свое сообщение? как его обработать в dialog-based приложении 
PM MAIL ICQ   Вверх
SergeCpp
Дата 30.6.2006, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 5
Всего: 124



WM_IDLEUPDATECMDUI

В MSDN по поиску находится несколько ссылок...

AFXPRIV.H
#define WM_IDLEUPDATECMDUI  0x0363  // wParam == bDisableIfNoHandler
   

Это сообщение отредактировал(а) SergeCpp - 30.6.2006, 10:34
PM MAIL WWW ICQ   Вверх
Earnest
Дата 30.6.2006, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Да, это сообщение определено в afxpriv.h, также как макрос ON_MESSAGE_VOID.
Сообщение рассылается всем окнам при вхождении в холостой цикл.

Цитата(takedo @  30.6.2006,  09:43 Найти цитируемый пост)
 Только иногда можно ведь в OnIddle и вообще не попасть? 

Если все делать правильно - нельзя! smile Idle-сообщение приходит железно.
Пользуюсь обновлением и синхронизацией on-idle несколько лет - метод ни разу не подводил. Конечно, это не панацея от всех случаев - иногда нужна синхронная обработка.
Но если достаточно асинхронной (90% случаев), то это - самый лучший метод: не порождает лишних зависимостей, практически бесплатный, позволяет подключить любое число подписчиков, а уж простой-то - дальше некуда.
 


--------------------
...
PM   Вверх
DeadSoul
Дата 1.7.2006, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

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



Цитата(deniska @  30.6.2006,  08:01 Найти цитируемый пост)
Цитата
Конечно, доступ к данным объекта нужно защитить хотя бы critical section.
А зачем? я всегда думал что если один поток ТОЛЬКО записывает данные в некую структуру например, а второй ТОЛЬКО считывает их оттуда, то синхронизация не нужна. Я не прав? 

Это неверно. Представь, что у тебя данные = две интовые переменные. При такой последовательности действий:
- writer изменил первую переменную
- стал активным поток reader(writer не успел изменить вторую переменную)
- reader отобразил(на диалог\консоль) эти две переменнные. Это может не являтся валидной парой переменных 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
deniska
Дата 3.7.2006, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 398
Регистрация: 1.7.2005
Где: Троицк

Репутация: 1
Всего: 0



Вобщем народ спасибо всем кто откликнулся. Оцените:
В потоке GUI по нажатию на кнопку запускается мильтимедийный таймер (собственно второй поток).
каждый раз после выполнения определенных действий этот поток обновляет значения в определенной структуре, после чего посылает GUI PostMessage какой-нибудь WM_USER+1, и GUI поток по этому сообщению считывает значения из структуры и обновляет контролы. Обращения к структуре все в CriticalSection.
На сколько кривой способ? 
PM MAIL ICQ   Вверх
takedo
Дата 3.7.2006, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



нинасколько

Добавлено @ 09:45 
да, тлоько вот  можешь ещё попробовать как Earnest, тогда не надо слать сообщение. 


--------------------
я не гольфист - я хоккеист
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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