Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проверьте поток с классом, Приложение на MFC с потоком и таймером 
:(
    Опции темы
Etud
Дата 24.8.2010, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Приложение на MFC с потоком и таймером.
При нажатии кнопки Button1 создается динамический объект f класса Filter, который используется для получения числа в рабочей фукции потока.
int r = f->getRes();

К числу добавляется 1 и результат выводится в Edit Control (m_Edit).
f->setRes();

В процессе работы данные объекта f могут изменяться. Для их получения использую таймер. В функции OnTimer() вызываю метод
f->getSeek();
и вывожу во второй Edit Control (m_Edit2).

Вопросы:
1) Правильно ли объявлен указатель f моего класса Filter(Filter *f;) в исходнике Thread3Dlg.cpp перед рабочей функцией потока. Т.е. он глобальный, а в хэдере Thread3Dlg.h сделать это не получается.
#include "Filter.h"
Filter *f;
2) Надо ли при работе с таймером для синхронизации применять, например, критические секции. 
3) Можно ли один метод класса Filter использовать в одном потоке f->getRes(), а другой в потоке приложения f->getSeek().

P.S.
C MFC имею маленький опыт работы.


Filter.h
Код

#ifndef _Filter_h_ 
#define _Filter_h_


class Filter
{ 

    public:
        Filter();
        int getRes();          //получить число
        void setRes(int x); // установить новое число
        int getSeek();      // найти новое число

    private:
        int z;
};

#endif


Filter.cpp
Код

#include "stdafx.h"
#include "Filter.h"

Filter::Filter()
{
    z = 5;
}

int Filter::getRes()
{
    return z;
}

void Filter::setRes(int x)
{
    z = x;
}

int Filter::getSeek()
{
    return z;
}


В диалоге 
Thread3Dlg.cpp
Код

#include "Filter.h"
Filter *f;

// Рабочая функция потока
UINT TextThreadProc(LPVOID param)
{
    CString szTemp;
    CThread3Dlg* pt = (CThread3Dlg*) param;

    int r = f->getRes();

    for(int i=0; i < 20; i++)
    {
        szTemp.Format(L"Num = " ) ;
        pt->m_Edit.ReplaceSel(szTemp);
        szTemp.Format(L"%d \r\n",  r++);
        f->setRes(r);
        pt->m_Edit.ReplaceSel(szTemp);
        Sleep(1000);
    }

    return 0;
}

// CThread3Dlg dialog
CThread3Dlg::CThread3Dlg(CWnd* pParent /*=NULL*/)
    : CDialog(CThread3Dlg::IDD, pParent)
{
    //…
}


// Нажали кнопку, создали объект f, запустили поток
void CThread3Dlg::OnBnClickedButton1()
{
    f = new Filter;

    // Считывание состояния диалогового окна
    UpdateData();
    // Запуск рабочих потоков
    AfxBeginThread(TextThreadProc, this);
}


// Функция таймера
void CThread3Dlg::OnTimer(UINT_PTR nIDEvent)
{

    CString szTemp2;
    szTemp2.Format(L"Num = " ) ;
    m_Edit2.ReplaceSel(szTemp2);
    szTemp2.Format(L"%d \r\n", f->getSeek() );
    m_Edit2.ReplaceSel(szTemp2);


    CDialog::OnTimer(nIDEvent);
}


Подскажите и покритикуйте плиз.
PM MAIL   Вверх
Etud
Дата 29.8.2010, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм...И чего так слабо ?

Неужели ни по одному вопросу ?
PM MAIL   Вверх
Earnest
Дата 30.8.2010, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Etud @  24.8.2010,  13:27 Найти цитируемый пост)
1) Правильно ли объявлен указатель f моего класса Filter(Filter *f;) в исходнике Thread3Dlg.cpp перед рабочей функцией потока. Т.е. он глобальный, а в хэдере Thread3Dlg.h сделать это не получается.
#include "Filter.h"
Filter *f;
2) Надо ли при работе с таймером для синхронизации применять, например, критические секции. 
3) Можно ли один метод класса Filter использовать в одном потоке f->getRes(), а другой в потоке приложения f->getSeek().

P.S.
C MFC имею маленький опыт работы.

Код влом читать, много букв. А вопросы говорят о том, что у тебя не только с MFC маленький опыт, но и спотоками вообще, и даже с C++.
1. Глобальные переменные нельзя определять в хедерах, только объявлять (т.е. используя extern), иначе получишь ошибки линковки.
2. С таймером - не надо, а вот для доступа к общим данным - не помешает.
3. Можно, если реализация потоко-безопасна, т.е. методы реентерабельны, а доступ к данным защищен.


--------------------
...
PM   Вверх
Etud
Дата 30.8.2010, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за ответик !  smile 

Цитата(Earnest @  30.8.2010,  15:54 Найти цитируемый пост)
1. Глобальные переменные нельзя определять в хедерах, только объявлять (т.е. используя extern), иначе получишь ошибки линковки.


Вы не правильно поняли.
Это не переменная, а указатель. А дальше пошла рабочая функция потока.

Код

#include "Filter.h"
Filter *f;


При нажатии кнопки создаем объект, в рабочей функции уже вызываем метод:
Код

f->getRes();


А по другому у меня не получается ! Это же не в самом классе приложения MFC, видимости и доступа к нему нет.

Добавлено @ 16:45
Цитата(Earnest @  30.8.2010,  15:54 Найти цитируемый пост)
2. С таймером - не надо, а вот для доступа к общим данным - не помешает.


Несмотря на свой ничтожный опыт и чтения про таймер
можно встретить рекомендации и так и этак !

Если работает с общими данными, разве не надо делать синхронизацию данных ???
Надо ведь.


Это сообщение отредактировал(а) Etud - 30.8.2010, 16:46
PM MAIL   Вверх
Earnest
Дата 31.8.2010, 06:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Etud @  30.8.2010,  17:30 Найти цитируемый пост)
Это не переменная, а указатель. А дальше пошла рабочая функция потока.

Потрясающе. А указатель, по-твоему, не переменная?
Цитата(Etud @  30.8.2010,  17:30 Найти цитируемый пост)
Несмотря на свой ничтожный опыт и чтения про таймер
можно встретить рекомендации и так и этак !

Если работает с общими данными, разве не надо делать синхронизацию данных ???

Надо, но таймер здесь совершенно не причем. Если просто таймер, без обращения из разных потоков к общим данным - не надо. Если есть обращение к общим данным, неважно как организованное, практически всегда надо. "Практически", т.к. если только чтение, то тоже не надо. Ну и т.д. Почитал бы Рихтера, что ли. 
Цитата(Etud @  30.8.2010,  17:30 Найти цитируемый пост)
А по другому у меня не получается ! Это же не в самом классе приложения MFC, видимости и доступа к нему нет.

Да причем здесь MFC? Если есть где-то какой-то объект, то для доступа к нему нужен указатель (ссылка), по другому не бывает.
Глобальные переменные - самый худший вариант обеспечения общего доступа к объекту. 
Как вариант, рассмотри возможность передачи указателя на объект в функцию потока. А то привыкнешь к глобальным переменным, а неправильные привычки потом мешать будут.




--------------------
...
PM   Вверх
Etud
Дата 31.8.2010, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Earnest @  31.8.2010,  06:33 Найти цитируемый пост)
А указатель, по-твоему, не переменная?


Да-да ! Ошибся, каюсь.  smile 


Цитата(Earnest @  31.8.2010,  06:33 Найти цитируемый пост)
Почитал бы Рихтера, что ли. 

Конечно можно, но позже.
Форум тогда зачем.

Цитата(Earnest @  31.8.2010,  06:33 Найти цитируемый пост)
Да причем здесь MFC? 

Эээ, поток то с GUI увязан.


Цитата(Earnest @  31.8.2010,  06:33 Найти цитируемый пост)
Глобальные переменные - самый худший вариант обеспечения общего доступа к объекту. 

Снова согласен. Это просто пример был. 


Цитата(Earnest @  31.8.2010,  06:33 Найти цитируемый пост)
Как вариант, рассмотри возможность передачи указателя на объект в функцию потока. А то привыкнешь к глобальным переменным, а неправильные привычки потом мешать будут.

Это мне понятно.

Сделаю новый вариант - напишу !

PM MAIL   Вверх
Etud
Дата 31.8.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Переработанная версия с передачей объекта f в качестве параметра в функцию
для создания потока.

Итак:

1) В заголовке класса Dlg.h объявили переменную-указатель f
Filter *f;

2) В обработчике кнопки создаем объект f, в методах
устанавливаем идентификатор окна и адрес текущего объекта,
создаем поток с рабочей функцией и объектом-параметром

Код

f = new Filter;
f->setHWnd(m_hWnd);
f->setThis(this);

// Считывание состояния диалогового окна
UpdateData();

    
AfxBeginThread(TextThreadProc, f);



3) Рабочая функция потока

Код

UINT TextThreadProc(LPVOID param)
{
CString szTemp;

Filter* f = (Filter*) param;
HWND h1 = f->getHWnd();

LPVOID ap = f->getThis();

//CThread3Dlg* pt = (CThread3Dlg*) ap;
    
// приведение в стиле С++
CThread3Dlg* pt = static_cast<CThread3Dlg*> (ap) ;

int r = f->getRes();

pt->m_Edit.ReplaceSel(szTemp);


return 0;
}



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


 




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


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

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