Подскажите про потоки (ответа я не нашел)
От: Mandigal  
Дата: 25.02.04 13:57
Оценка:
У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток

Делаю как в хелпах писано
Глобальную управляющую функцию
UINT MyThreadProc( LPVOID pParam )
{

CTestDlg::testThread();
return 0;
}
и ее вызов

void CTestDlg::OnBnClickedB1()
{
AfxBeginThread(MyThreadProc,NULL);
}

Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.
Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )
Re: Подскажите про потоки (ответа я не нашел)
От: BlackHeretic Израиль  
Дата: 25.02.04 14:02
Оценка:
Здравствуйте, Mandigal, Вы писали:

M>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток


M>Делаю как в хелпах писано

M>Глобальную управляющую функцию
M>UINT MyThreadProc( LPVOID pParam )
M>{

M> CTestDlg::testThread();

M>return 0;
M>}
M>и ее вызов

M>void CTestDlg::OnBnClickedB1()

M>{
M>AfxBeginThread(MyThreadProc,NULL);
M>}

M>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.

M>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )

Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage.
Номер сообщения получай через RegiterWindowMessage
Удачи
ICQ 156156278
Re: Подскажите про потоки (ответа я не нашел)
От: Vamp Россия  
Дата: 25.02.04 14:39
Оценка:
CTestDlg::testThread() статическая?
Если нет, то твой код не скомпилируется.
Если да, то она не будет иметь доступ к нестатическим членам класса CTestDlg.
Мораль — делаем так:

UINT MyThreadProc( LPVOID pParam ) {
    static_cast<CTestDlg*>(pParam)->testThread(); 
         return 0;
}

void CTestDlg::OnBnClickedB1() {
    AfxBeginThread(MyThreadProc, this);
}
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Подскажите про потоки (ответа я не нашел)
От: Mandigal  
Дата: 25.02.04 14:42
Оценка:
Здравствуйте, BlackHeretic, Вы писали:

BH>Здравствуйте, Mandigal, Вы писали:


M>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток


M>>Делаю как в хелпах писано

M>>Глобальную управляющую функцию
M>>UINT MyThreadProc( LPVOID pParam )
M>>{

M>> CTestDlg::testThread();

M>>return 0;
M>>}
M>>и ее вызов

M>>void CTestDlg::OnBnClickedB1()

M>>{
M>>AfxBeginThread(MyThreadProc,NULL);
M>>}

M>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.

M>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )

BH>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage.

BH>Номер сообщения получай через RegiterWindowMessage
BH>Удачи

Хорошо, я передал HWND диалога с помощью GetSafeHwnd()
а дальше мне его как использовать?
и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает
Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать
Re[2]: Подскажите про потоки (ответа я не нашел)
От: BlackHeretic Израиль  
Дата: 25.02.04 14:43
Оценка:
Здравствуйте, Vamp, Вы писали:

V>CTestDlg::testThread() статическая?

V>Если нет, то твой код не скомпилируется.
V>Если да, то она не будет иметь доступ к нестатическим членам класса CTestDlg.
V>Мораль — делаем так:

V>
V>UINT MyThreadProc( LPVOID pParam ) {
V>    static_cast<CTestDlg*>(pParam)->testThread(); 
V>         return 0;
V>}

V>void CTestDlg::OnBnClickedB1() {
V>    AfxBeginThread(MyThreadProc, this);
V>}
V>


Тока можно на неприятности нарваться, если обратиться к одним и тем же данным...
ИМХО сообщения надежней
ICQ 156156278
Re[3]: Подскажите про потоки (ответа я не нашел)
От: BlackHeretic Израиль  
Дата: 25.02.04 14:49
Оценка:
Здравствуйте, Mandigal, Вы писали:

M>Здравствуйте, BlackHeretic, Вы писали:


BH>>Здравствуйте, Mandigal, Вы писали:


M>>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток


M>>>Делаю как в хелпах писано

M>>>Глобальную управляющую функцию
M>>>UINT MyThreadProc( LPVOID pParam )
M>>>{

M>>> CTestDlg::testThread();

M>>>return 0;
M>>>}
M>>>и ее вызов

M>>>void CTestDlg::OnBnClickedB1()

M>>>{
M>>>AfxBeginThread(MyThreadProc,NULL);
M>>>}

M>>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.

M>>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )

BH>>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage.

BH>>Номер сообщения получай через RegiterWindowMessage
BH>>Удачи

M>Хорошо, я передал HWND диалога с помощью GetSafeHwnd()

M>а дальше мне его как использовать?
M>и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает
M>Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать

Вызывать методы из другого потока, особенно которые меняют что-то, небезопасно. Как минимум данные могут быть не корректны. А сообщение придет в рамках потока диалога и не с кем не законфликтует. Ловить это лучше в WindowProc диалога. Просто я тока вчера написал реализацию подобной байды — тока у меня нужно было по HTTP кое что скачивать. Все чудненько работает
ICQ 156156278
Re[4]: Подскажите про потоки (ответа я не нашел)
От: Mandigal  
Дата: 25.02.04 21:43
Оценка:
Здравствуйте, BlackHeretic, Вы писали:

BH>Здравствуйте, Mandigal, Вы писали:


M>>Здравствуйте, BlackHeretic, Вы писали:


BH>>>Здравствуйте, Mandigal, Вы писали:


M>>>>У меня есть в проге длительная операция (рассчет CRC32 для файлов больше 1GB) и я хочу для нее создать отдельный рабочий поток


M>>>>Делаю как в хелпах писано

M>>>>Глобальную управляющую функцию
M>>>>UINT MyThreadProc( LPVOID pParam )
M>>>>{

M>>>> CTestDlg::testThread();

M>>>>return 0;
M>>>>}
M>>>>и ее вызов

M>>>>void CTestDlg::OnBnClickedB1()

M>>>>{
M>>>>AfxBeginThread(MyThreadProc,NULL);
M>>>>}

M>>>>Но естественно глобальная MyThreadProc не может видеть CTestDlg::testThread(); (ну или я подставлял содерживое testThread(), там тоже все рассчитано что функция выполняется в классе CTestDlg), мне знакомый посоветовал что можно объявить MyThreadProc как член класса CTestDlg и просто написать оболочку(глобальную) для запуска ее, но у меня не получилось.

M>>>>Пожалуйста подскажите как, если можно с примерами, потому как я с потоками вообще еще не работал и пока непонимаю принципов (прочтение MSDN не помогло ( )

BH>>>Вместо NULL передавай HWND диалога. А как закончишь расчет перешли результат через SendMessage.

BH>>>Номер сообщения получай через RegiterWindowMessage
BH>>>Удачи

M>>Хорошо, я передал HWND диалога с помощью GetSafeHwnd()

M>>а дальше мне его как использовать?
M>>и зачем мне передавать что-то через SendMessage если функция CTestDlg::testThread() и так сама в эдитбоксы значения записывает
M>>Суть в том что в CTestDlg::testThread() находиться тот же код который раньше был в CTestDlg::OnBnClickedB1(), просто я хотел эту всю операцию отдельным потоком сделать

BH>Вызывать методы из другого потока, особенно которые меняют что-то, небезопасно. Как минимум данные могут быть не корректны. А сообщение придет в рамках потока диалога и не с кем не законфликтует. Ловить это лучше в WindowProc диалога. Просто я тока вчера написал реализацию подобной байды — тока у меня нужно было по HTTP кое что скачивать. Все чудненько работает


Спасибо Vamp метод помог решить задачу, в моем приложении в этом потоке просто в эдит боксы добавляются значения CRC32 файлов так что по идее тут конфликтовать не чему (просто набросок проги пока, иначе кто бы стал в одной функции делать и рассчет CRC32 и вывод результатов в окно )
Но по идее вариант предложенный BlackHeretic должен быть конечно понадежнее, буду смотреть как его реализовывать, я же просто пока вообще всегда работал с одним потоком (необходимости не было)
Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо
Спасибо всем большое!
Re[5]: Подскажите про потоки (ответа я не нашел)
От: BlackHeretic Израиль  
Дата: 26.02.04 08:12
Оценка:
Здравствуйте, Mandigal, Вы писали:

M>Здравствуйте, BlackHeretic, Вы писали:


M>Спасибо Vamp метод помог решить задачу, в моем приложении в этом потоке просто в эдит боксы добавляются значения CRC32 файлов так что по идее тут конфликтовать не чему (просто набросок проги пока, иначе кто бы стал в одной функции делать и рассчет CRC32 и вывод результатов в окно )

M>Но по идее вариант предложенный BlackHeretic должен быть конечно понадежнее, буду смотреть как его реализовывать, я же просто пока вообще всегда работал с одним потоком (необходимости не было)
M>Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо
M>Спасибо всем большое!

Могу — мыло давай
ICQ 156156278
Re[5]: Подскажите про потоки (ответа я не нашел)
От: BlackHeretic Израиль  
Дата: 26.02.04 08:36
Оценка:
Здравствуйте, Mandigal, Вы писали:

M>Кстати BlackHeretic если есть вариант реализованный так как ты описал, то не мог бы ты мне его на мыло скинуть (скелет, просто кому кто и когда что передает), ну это я уже по собственной лени так как еще не смотрел что там вообще делать надо


А собственно вот и код
Юзайте

BOOL CTPingerDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

// Заскипано

        m_message = RegisterWindowMessage(_T("SomeStringThatIWant"));
    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTPingerDlg::OnBnClickedRun()
{
    CPingThread* pPingThread = new CPingThread(m_hWnd, m_message, url, include, exclude);
    pPingThread->CreateThread();
}

LRESULT CTPingerDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    if(message == m_message)
    {
        ProcessResultsOfThread(wParam);
        delete (CPingThread*)lParam;
        return 0;
    }

    return CDialog::WindowProc(message, wParam, lParam);
}

class    CPingThread
{
    HWND m_hWnd;
    UINT m_message;
    CString m_url;
    CString m_incl;
    CString m_excl;
public:
    CPingThread(HWND hWnd, UINT message, const CString& url, const CString& incl, const CString& excl) : m_hWnd(hWnd), m_message(message),m_url(url), m_incl(incl), m_excl(excl) {}
    static    DWORD    Run(CPingThread* pPT);
    void    CreateThread();
};

DWORD CPingThread::Run(CPingThread* pPT)
{
    CHttpFileReader fr;
    SendMessage(pPT->m_hWnd, pPT->m_message, (WPARAM)fr.IsAvailable(pPT->m_url, pPT->m_incl, pPT->m_excl), (LPARAM)pPT);
        // Здесь можно было бы написать "delete pPT", только тогда не забыть компилить как многопоточное приложение
    return 0;
}

void CPingThread::CreateThread()
{
    DWORD id;
    ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Run, this, 0, &id);
}
ICQ 156156278
Re[6]: Подскажите про потоки (ответа я не нашел)
От: Mandigal  
Дата: 26.02.04 10:35
Оценка:
Спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.