Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сделать аналог SendMessage, именно для потока, а не для окна. 
V
    Опции темы
Earnest
Дата 25.1.2006, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Нет, так мы далеко зайдем smile
Насколько вероятна ситуация, когда несколько потоков синхронно обратятся к одному? Даже если это возможно, то достаточно добавить в класс потока еще критическую секцию и прикрыть ею весь код SendTreadMessage. Тогда двух событий на поток достаточно. И будет у нас по принципу: кто первый, того и тапки. А остальные подождут.
Сам подумай: даже если SendThreadMessage вызывается разными потоками, в результате-то будет работать только один (к которому обратились)! Т.е. в один момент может обрабатываться только чей-нибудь один запрос.

Про чужое событие никто не узнает smile , ведь вся обработка событий инкапсулирована внутри класса потока, и события у него свои...

Даже если у тебя потоки хаотично друг к другу обращаются (синхронно!), и никто не хочет ждать, все равно придется как-то их в очередь строить... приоритеты назначать ... и понеслось ... в результате получаем новый Windows Kernel ... старый нафик выбрасываем (наш, конечно, лучше smile ) ...

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


--------------------
...
PM   Вверх
Dreamer_0x01
Дата 25.1.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Терминатор
**


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

Репутация: 9
Всего: 12



Цитата(Earnest @ 25.1.2006, 18:07 Найти цитируемый пост)

Насколько вероятна ситуация, когда несколько потоков синхронно обратятся к одному?

Очень даже. У меня программа будет работать с несколькими прибораи одновременно по разным интерфейсам (ком-порты, Ethernet, и в перспективе еще и USB), на каждый планируется создать свой поток.

Цитата(Earnest @ 25.1.2006, 18:07 Найти цитируемый пост)

Даже если это возможно, то достаточно добавить в класс потока еще критическую секцию и прикрыть ею весь код SendTreadMessage

smile точно! Как я не догадался... Все гениальное - просто!
Earnest, ты профи! smile
Добавлено @ 18:52
Цитата(Earnest @ 25.1.2006, 18:07 Найти цитируемый пост)

придется как-то их в очередь строить... приоритеты назначать ... и понеслось ... в результате получаем новый Windows Kernel ... старый нафик выбрасываем (наш, конечно, лучше  )


А ведь точно, это мысль..



--------------------
Нет ничего невозможного. Есть цели, и есть время и силы на их достижение.
PM ICQ   Вверх
Dreamer_0x01
Дата 5.2.2006, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Терминатор
**


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

Репутация: 9
Всего: 12



Ну что, уже достаточно давно пользуюсь своей консрукцией, пока работает.


может, тут есть какие-то подводные камни? Щас-то приложение маленькое, но вот на днях буду его очень сильно расширять.

Вот код:

собственно, класс
Код

struct SYNCSTRUCT{//синхронизирующая структура
    CEvent SyncDetect;//определяет, была ли посылка синхронного сообщения
    CEvent EventReady;//готовность обработки синхронного сообщения
    CRITICAL_SECTION cs;
};

class MyThread : public CWinThread
{
    DECLARE_DYNCREATE(MyThread)
private:
    SYNCSTRUCT m_SyncEvents;
protected:
    MyThread();           // protected constructor used by dynamic creation
    virtual ~MyThread();
    DECLARE_MESSAGE_MAP()

public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
    virtual BOOL PumpMessage();
    BOOL SendThreadMessage(UINT message, WPARAM wParam, LPARAM lParam);//собственно, все ради этого
protected:
    void ReplyMessage(void);
};


Описание класса
Код

IMPLEMENT_DYNCREATE(MyThread, CWinThread)

MyThread::MyThread()
{
    this->m_SyncEvents.EventReady.ResetEvent();//во избежание взаимной блокировки
    this->m_SyncEvents.SyncDetect.ResetEvent();
    ::InitializeCriticalSection(&this->m_SyncEvents.cs);
}

MyThread::~MyThread()
{
    ::DeleteCriticalSection(&this->m_SyncEvents.cs);
}

BOOL MyThread::InitInstance()
{
    this->m_bAutoDelete=TRUE;
    return TRUE;
}

int MyThread::ExitInstance()
{
    return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(MyThread, CWinThread)
END_MESSAGE_MAP()

BOOL MyThread::PumpMessage()
{
    BOOL result= CWinThread::PumpMessage();
    if(this->m_SyncEvents.SyncDetect.Lock(0))
    {
        this->m_SyncEvents.EventReady.SetEvent();
    }
    return result;
}

BOOL MyThread::SendThreadMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
    ::EnterCriticalSection(&this->m_SyncEvents.cs);
    this->m_SyncEvents.SyncDetect.SetEvent();
    BOOL result=this->PostThreadMessage(message,wParam,lParam);
    this->m_SyncEvents.EventReady.Lock();
    ::LeaveCriticalSection(&this->m_SyncEvents.cs);
    return result;
}

void MyThread::ReplyMessage(void)
{
    this->m_SyncEvents.EventReady.SetEvent();
}



Использование
Код

class WorkThread : public MyThread
{
//и понеслась вставлять обработчики своих сообщений
}

//а в самом приложении сначала объявляем
WorkThread * m_WorkThread;

//потом делаем 
    CRuntimeClass* prt = RUNTIME_CLASS( WorkThread );
    ASSERT( lstrcmp( prt->m_lpszClassName, "WorkThread" )  == 0 );
    this->m_WorkThread=(WorkThread*)AfxBeginThread(prt);

//ну и далее собственно уже можно слать сообщения: )
this->m_WorkThread->SendThreadMessage(/*......*/);

//ну а убиваем поток так:
this->m_WorkThread->PostThreadMessage(WM_QUIT,0,0);



Вот у меня вопрос - правильно ли я сделал ReplyMessage(), или тут есть какие-то "подковырки"? smile




--------------------
Нет ничего невозможного. Есть цели, и есть время и силы на их достижение.
PM ICQ   Вверх
Earnest
Дата 6.2.2006, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Вроде нормально... раз пока работает... smile

Но если собираешься сильно расширять, то используй вместо CRITICAL_SECTION CCriticalSection, а вместо Enter/Leave - CSingleLock.
Во-первых много строчек кода уйдет, что само по себе неплохо. Во-вторых, смесь CEvent и "просто" CRITICAL_SECTION выглядит, как бы это помягче сказать smile ... странно.
В-третьих - код будет безопаснее по отношению к исключениям - это тебе обеспечит идиома "захват ресурса есть инициализация".
В-четвертых, вызовы ...ResetEvent в конструкторе совершенно излишни, т.к. CEvent по умолчанию создается не в сигнальном состоянии.

И зачем все эти this-> ?


--------------------
...
PM   Вверх
Dreamer_0x01
Дата 6.2.2006, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Терминатор
**


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

Репутация: 9
Всего: 12



Цитата(Earnest @ 6.2.2006, 18:41 Найти цитируемый пост)

Вроде нормально... раз пока работает...

НУ в двух потоках работает все прекрасно. Единственное, почему-то были глюки при выхове функций из...того же самого потока. Правда, с этим я постепенно и сам разберусь, может быть, неправильно что-то вызываю.
Вот скоро буду проверять на четырех, там и поглядим.
Цитата(Earnest @ 6.2.2006, 18:41 Найти цитируемый пост)

используй вместо CRITICAL_SECTION CCriticalSection, а вместо Enter/Leave - CSingleLock

Ага. Сделаю. Видишь ли, я самоучка, и до чего первого дошел, то и прижилось во всех программах smile

Цитата(Earnest @ 6.2.2006, 18:41 Найти цитируемый пост)

В-третьих - код будет безопаснее по отношению к исключениям

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

Цитата(Earnest @ 6.2.2006, 18:41 Найти цитируемый пост)

И зачем все эти this-> ?

А так бысрее код набирать текст программы - набираешь this->, и студия тебе выдает списочек всех членов класса, удобно, нажал одну-две клавиши вместо десятка - и элемент вписан. Только лишь ради этого ;)
Компилятор же я так понял все равно все лишнее выкинет?

Это сообщение отредактировал(а) Dreamer_0x01 - 6.2.2006, 20:09


--------------------
Нет ничего невозможного. Есть цели, и есть время и силы на их достижение.
PM ICQ   Вверх
Earnest
Дата 6.2.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Dreamer_0x01 @ 6.2.2006, 19:52 Найти цитируемый пост)

Компилятор же я так понял все равно все лишнее выкинет?

Скорее вставит, если этого this-> нет. Формально все правильно, но ИМХО, код более громоздкий и поэтому хуже читаемый. Я предпочитаю классовые переменные с префиксом "m_" делать, чтобы сразу видно было ху из ху. А скорость набора на скорость конечную написания кода не влияет. Кстати, у тебя есть Visual Assist? Если нет, найди и поставь, очень рекомендую (и в смысле автодополнения тоже).

Цитата(Dreamer_0x01 @ 6.2.2006, 19:52 Найти цитируемый пост)

Кстати, где бы почитать что-то вразумительное про эти самые исключения, русскоязычное?

Исключениям посвящена изрядная часть книги Саттера "Решение сложных задач на С++", здесь на форуме в разделе C++ обсуждалась, может и ссылки на электронную версию есть.
И его же продолжение "Новые сложные задачи на С++". А еще, по-моему Мейерс на эту тему писал: "50 советов по эффективному использованию С++", "Еще 35 советов" про то же самое, а также "Эффективное использование STL". Названия приблизительные.
Я бы советовала начать с Мейерса, мне кажется у него более доступно. Все книжки небольшие, и все из серии must read.



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


Терминатор
**


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

Репутация: 9
Всего: 12



Цитата(Earnest @ 6.2.2006, 22:11 Найти цитируемый пост)

"Решение сложных задач на С++"


А вот это недавече как сегодня где-то видел, но смутило кричащее название, и пропустил. Завтра в поиске восстановлю сайтик, где это было выложено.

Цитата(Earnest @ 6.2.2006, 22:11 Найти цитируемый пост)

Кстати, у тебя есть Visual Assist

Нет, не стоит. А что эта штука кроме подсветки кода делает?
Добавлено @ 00:10
Цитата(Earnest @ 6.2.2006, 22:11 Найти цитируемый пост)

А скорость набора на скорость конечную написания кода не влияет

я понимаю, но когда я сам же забываю, как точно называется имя переменной - то приходится делать именно так.



--------------------
Нет ничего невозможного. Есть цели, и есть время и силы на их достижение.
PM ICQ   Вверх
Earnest
Дата 7.2.2006, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Dreamer_0x01 @ 7.2.2006, 00:08 Найти цитируемый пост)

А вот это недавече как сегодня где-то видел, но смутило кричащее название, и пропустил. Завтра в поиске восстановлю сайтик, где это было выложено.

Ну это переводчики постарались, оригинальное название "Exceptional C++".
Там просто стиль изложения такой: ставится задача, потом решается.

Цитата(Dreamer_0x01 @ 7.2.2006, 00:08 Найти цитируемый пост)

Нет, не стоит. А что эта штука кроме подсветки кода делает?

VisualAssist у меня так давно, что я уже не помню, что он делает, а что сам MSVC. По-моему, я автодополнение MSVC и его же броузинг кода просто не использую, а использую VisualAssist (потому что лучше). Еще он вроде автоматически исправляет мелкие ошибки набора, показывает контекст текущего выражения и его определение. Плюс настраиваемые функции: генерация блоков текста по шаблонам. Очень удобно, например, в новые файлы стандартные шапки вставлять.



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


 




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


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

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