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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Посылка сообщений потоку 
:(
    Опции темы
Paspartu
Дата 4.3.2010, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Доброго времени суток! Есть класс:
Код

/////////////////////////////////////////////////////////////////////////////////////////////////
//    CWiseThread
class CWiseThread
{

public:
    HANDLE m_hThread;        //хэндл потока
    DWORD  m_dwThreadId;    //ID потока

public:
    CWiseThread();
    virtual ~CWiseThread();

    //    Создаёт поток
    //    param lpThreadAttributes атрибуты доступа
    //    param uiStackSize размер стэка
    //    param dwCreationFlags флаг
    //    return TRUE в случае успеха
    BOOL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL, unsigned int uiStackSize = 0, DWORD dwCreationFlags = CREATE_SUSPENDED);

    //    Возобновляет поток return TRUE в случае успеха
    BOOL Start()
    {
        return (::ResumeThread(m_hThread) != -1);
    }

    //    Выполняет завершение потока
    //    param dwMilliseconds - время в миллисекундах ожидания завершения потока
    //    return TRUE, если поток завершился коректно
    BOOL Cancel(DWORD dwMilliseconds); 

    //    Приостанавливает поток return TRUE в случае успеха
    BOOL Pause()
    {
        return (::SuspendThread(m_hThread) != -1); 
    }

    //    Отправляет сообщение потоку
    //    Msg Сообщение
    //    param wParam параметр 1
    //    param lParam параметр 2
    //    return TRUE в случае успеха
    BOOL PostThreadMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0)
    {
        return ::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam);
    }

    //    Устанавливает приоритет
    //    param nPiority Приоритет
    //    return TRUE в случае успеха
    BOOL SetThreadPriority(int nPiority)
    {
        
        return ::SetThreadPriority(m_hThread, nPiority);
    }

    //    Возвращает хендл потока
    operator HANDLE() const
    {
        return m_hThread;
    }

    BOOL IsRun()
    {
        return m_fRunThread;
    }

    
private:
    static unsigned WINAPI ThreadProc(LPVOID param);    // Фукнция потока

protected:
    virtual BOOL Process();                                    // Рабочая функция return FALSE, если функция завершает работу потока
    virtual BOOL OnDone();


private:
    volatile BOOL m_fRunThread; // Флаг, состояния потока если FALSE, то обработчики сообщений потока должны немедленно завершать свою работу
};



Код

/////////////////////////////////////////////////////////////////////////////////////////////////
//    CWiseThread
CWiseThread::CWiseThread(void):
m_hThread(NULL)
{
    m_dwThreadId = 0;
}

CWiseThread::~CWiseThread(void)
{
    Cancel(0);
    ::CloseHandle(m_hThread);
}

//===========================================================================    CreateThread
BOOL CWiseThread::CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, unsigned int uiStackSize, DWORD dwCreationFlags)
{
    
    //m_hThread = (HANDLE)_beginthreadex(lpThreadAttributes, uiStackSize, ThreadProc, (LPVOID)this, dwCreationFlags, (unsigned*)&m_dwThreadId); 
    m_hThread = (HANDLE)::CreateThread(lpThreadAttributes, uiStackSize, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)this, dwCreationFlags, &m_dwThreadId); 

    if(m_hThread)
        m_fRunThread = TRUE;

    return (m_hThread != NULL);
}

//===========================================================================    Quit
BOOL CWiseThread::Cancel(DWORD dwMilliseconds)
{
    m_fRunThread = FALSE;
    SetThreadPriority(THREAD_PRIORITY_HIGHEST);
    DWORD res = PostThreadMessage(WM_QUIT);

    return (WaitForSingleObject(*this, dwMilliseconds) == WAIT_OBJECT_0);
}

//===========================================================================    ThreadProc
unsigned WINAPI CWiseThread::ThreadProc(LPVOID param)
{
    CWiseThread* pThread = (CWiseThread*)param;

    MSG msg;
    BOOL fDone = FALSE;

    while(!fDone)
    {
        //GetMessage(&msg, NULL, 0, 0)
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))   
        {
            if (msg.message == WM_QUIT)
                fDone = TRUE;                                  
        }
        else
        {
            if (!pThread->Process())
                break;
        }
    }

    pThread->m_fRunThread = FALSE;
    pThread->OnDone();

    return 0;
}

//===========================================================================    Process
BOOL CWiseThread::Process()
{
    return TRUE;
}

//===========================================================================    OnDone
BOOL CWiseThread::OnDone()
{
    return TRUE;
}


Вопрос такой при попытке вызова Cancel() выполняется
Код

BOOL PostThreadMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0)
    {
        return ::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam);
    }


::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam) возвращает 0 т.е. выполняется с ошибкой -> сообщение в PeekMessage() не ловится -> функция потока не завершается, проблема скорее всего в том, что нет очереди сообщений потока, как её установить? И как вообще правильно передавать сообщения потоку, например об принудительном выходе из функции потока или передачи в него каких либо данных?
PM MAIL   Вверх
GremlinProg
Дата 4.3.2010, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(PostThreadMessage Function @  MSDN)

Microsoft Windows Vista and later. When a message is blocked by UIPI the last error, retrieved with GetLastError, is set to 5 (access denied).

The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use the following method to handle this situation: 
Create an event object, then create the thread. Use the WaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage as shown here to force the system to create the message queue. 
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)
Set the event, to indicate that the thread is ready to receive posted messages.


Добавлено через 5 минут и 14 секунд
Цитата(Paspartu @  4.3.2010,  22:08 Найти цитируемый пост)
ак вообще правильно передавать сообщения потоку

как обычный PostMessage, тут ничего особого нет, разве что со стороны потока член hwnd структуры MSG будет нулевой


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


Шустрый
*


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

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



To GremlinProg, спасибо, буду создавать event для создания очереди...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0456 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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