Передача ссылок в поток в частности объектов класс CFormView
От: Pats Россия  
Дата: 06.05.03 14:46
Оценка:
Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:

CMyView * CMyView::GetView()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

if ( !pChild )
return NULL;

CView * pView = pChild->GetActiveView();

if ( !pView )
return NULL;

// Fail if view is of wrong kind
if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) )
return NULL;

return (CMyView *) pView;
}

Затем передаю его в парамметрах потока:

CMyView *mon = GetView();

HANDLE wrkThr=CreateThread(0, 0, unpack, (CMyView*)mon, 0, &wrkId);


Функция потока выглядит следующим образом:

DWORD WINAPI unpack(void* par)
{

........

return 0;

}

Как далее в функции потока преобразовать число принятое в парамметрах(par)
в класс CMyView?

Была такая попытка:

CMyView* parp=(CMyView)par;
CMyView* ppar=reinterpret_cast<CMyView>(*par);

, но она не увенчалась успехом.

И вообще как можно передавать указатели на объекты в потоки.
Искренне ваш.
Re: Передача ссылок в поток в частности объектов класс CForm
От: Serguei666 Беларусь  
Дата: 06.05.03 15:47
Оценка:
Здравствуйте, Pats, Вы писали:

P>Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:


P> CMyView * CMyView::GetView()

P> {
P> CMDIChildWnd * pChild =
P> ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

P> if ( !pChild )

P> return NULL;

P> CView * pView = pChild->GetActiveView();


P> if ( !pView )

P> return NULL;

P> // Fail if view is of wrong kind

P> if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) )
P> return NULL;

P> return (CMyView *) pView;

P> }

P>Затем передаю его в парамметрах потока:


P>CMyView *mon = GetView();


P>HANDLE wrkThr=CreateThread(0, 0, unpack, (CMyView*)mon, 0, &wrkId);



P>Функция потока выглядит следующим образом:


P>DWORD WINAPI unpack(void* par)

P>{

P> ........


P>return 0;


P>}


P>Как далее в функции потока преобразовать число принятое в парамметрах(par)

P>в класс CMyView?

P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);

P>, но она не увенчалась успехом.


P>И вообще как можно передавать указатели на объекты в потоки.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re: Сорри, сорвалось
От: Serguei666 Беларусь  
Дата: 06.05.03 15:51
Оценка:
Здравствуйте, Pats, Вы писали:

P>Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:


P> CMyView * CMyView::GetView()

P> {
P> }

Будем считать, что это работает...



P>Затем передаю его в парамметрах потока:

P>CMyView *mon = GetView();
P>HANDLE wrkThr=CreateThread(0, 0, unpack, (CMyView*)mon, 0, &wrkId);

"Пока все нормально" (с) ДДТ)


P>Функция потока выглядит следующим образом:


P>DWORD WINAPI unpack(void* par)

P>{ ...
P>return 0;
P>}

P>Как далее в функции потока преобразовать число принятое в парамметрах(par)

P>в класс CMyView?

P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);
P>, но она не увенчалась успехом.
Вы бы подрнее писали, что знанит "не увенчалась успехом". Хотя бы на каком этапе — компиляции или исполненния — т.е. ваш код не откомпилировался или программа крэшанулась.

Вам же к уазателю привести надо. Значит
CMyView* parp=(CMyView*)par;

P>И вообще как можно передавать указатели на объекты в потоки.


Вы все правильно делаете. Так и надо
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[2]: Сорри, сорвалось
От: Pats Россия  
Дата: 06.05.03 19:11
Оценка:
Здравствуйте, Serguei666, Вы писали:


P>Как далее в функции потока преобразовать число принятое в парамметрах(par)

P>в класс CMyView?

P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);
P>, но она не увенчалась успехом.
S>Вы бы подрнее писали, что знанит "не увенчалась успехом". Хотя бы на каком этапе — компиляции или исполненния — т.е. ваш код не откомпилировался или программа крэшанулась.

Это значит, что при обращении к этому объекту он не находит соответствующих ему методов и переменных.
Короче компилер ругается.

S>Вам же к уазателю привести надо. Значит

S>CMyView* parp=(CMyView*)par;

Ну дык класс CMyView не определен в функции потока. Глобальным его делать тоже нельзя.

S>Вы все правильно делаете. Так и надо


Интуитивно я тоже это понимаю, но вот как бы мне переменную преобразовать не знаю.
Искренне ваш.
Re[3]: Сорри, сорвалось
От: Serguei666 Беларусь  
Дата: 06.05.03 19:39
Оценка:
Здравствуйте, Pats, Вы писали:

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



P>Как далее в функции потока преобразовать число принятое в парамметрах(par)

P>в класс CMyView?

P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);
P>, но она не увенчалась успехом.
S>Вы бы подрнее писали, что знанит "не увенчалась успехом". Хотя бы на каком этапе — компиляции или исполненния — т.е. ваш код не откомпилировался или программа крэшанулась.

P>Это значит, что при обращении к этому объекту он не находит соответствующих ему методов и переменных.

P>Короче компилер ругается.

Так включите заголовок (H файл) с объявлением класса CMyView в ваш CPP файл, где приведенный код живет


S>Вам же к уазателю привести надо. Значит

S>CMyView* parp=(CMyView*)par;
P>Ну дык класс CMyView не определен в функции потока. Глобальным его делать тоже нельзя.

Не понял. Это вы о чем? Декларация (объявление) класса в любом случае "глобальна", если вы не используете специальных трюков (а я думаю, вы их не используете). Вам нужно только H файл включить в нужное место, о чем я и написал



P>Интуитивно я тоже это понимаю, но вот как бы мне переменную преобразовать не знаю.


Я же вам написал. Пользуйтесь на здоровье.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[4]: Сорри, сорвалось
От: IvanGrozny Германия http://IvanGrozny.de.vu
Дата: 07.05.03 07:42
Оценка:
Здравствуйте, Serguei666, Вы писали:

Пример из практики- я передаю поинтер на Сокет, но это не принципиально, так же должен функционировать поинтер на любой обьект.

в зависимости от compilera нужно иногда кастить его к void *


hProcess[i]=CreateThread( NULL,
0,routine,(LPVOID)socket,0,NULL);//socket==pointer k обьектy.


ULONG __stdcall routine(LPVOID socket)
{
BerkeleySocket* sock=(BerkeleySocket*)socket;
....
}
Re: Передача ссылок в поток в частности объектов класс CForm
От: Patalog Россия  
Дата: 07.05.03 08:25
Оценка:
Здравствуйте, Pats, Вы писали:

P>Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:


[]

В дополнение ко всему скзанному, хотел бы отметить несколько других моментов:
Неужели передавать нужно именно указатель на CMyView?
Ежели нужны некоторые _данные_ этого класса, так может лучше сделать что-то типа
struct my_transfer_data
{
     int data1;
     unsigned char data2[some_size];
     //some_type data3;
     //...
     //etc.
};
//далее делаем 
my_transfer_data* transfer_data = new my_transfer_data;
//заполняем структуру нужными данными и передаем указатель в поток.
HANDLE wrkThr=CreateThread(0, 0, unpack, transfer_data, 0, &wrkId);
//в потоке делаем
transfer_data = reinterpret_cast<my_transfer_data*>(par);
//и пользуемся данными

Ежели нужны некоторые ф-й класса (не связанные непосредственно с окном (HWND), имхо, лучше так же вынести их в отделный класс и передавать указатель на него.
Ежели нужна именно функциональность класса CMyView как _окна_ (для посылки сообщений, например), то лучше передавать HWND кна.
Почетный кавалер ордена Совка.
Re[5]: Очень хороший пример
От: Serguei666 Беларусь  
Дата: 07.05.03 15:44
Оценка:
Здравствуйте, IvanGrozny, Вы писали:

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


IG>Пример из практики- я передаю поинтер на Сокет, но это не принципиально, так же должен функционировать поинтер на любой обьект.


IG>в зависимости от compilera нужно иногда кастить его к void *



IG> hProcess[i]=CreateThread( NULL,

IG> 0,routine,(LPVOID)socket,0,NULL);//socket==pointer k обьектy.


IG>ULONG __stdcall routine(LPVOID socket)

IG>{
IG> BerkeleySocket* sock=(BerkeleySocket*)socket;
IG>....
IG>}

...Только непонятно, к чему он

У человека класс к моменту использования не задекларирован (насколько я могу судить по тем жидким сведениям, которые мне удалось из него выжать). Ваш пример к данной ошибке никак не относится.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[2]: Передача ссылок в поток в частности объектов класс CF
От: Serguei666 Беларусь  
Дата: 07.05.03 16:23
Оценка:
Здравствуйте, Patalog, Вы писали:

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


P>Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:


P>[]


P>В дополнение ко всему скзанному, хотел бы отметить несколько других моментов:

P>Неужели передавать нужно именно указатель на CMyView?

Ну в общем, думаю да. То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать). Это же сколько доп. действий вы предлагаете:
1. Создать структуру
2. Отследить, чтобы после вызова "new my_transfer_data" не забылось "delete"
3. Скопировать данные из view в структуру
4. Возможно, поддерживать копии данных в структуре в "up-to-date" состоянии (проще говоря, обновлять их)
5. Скопировать данные из структуры обратно во view
А все ради чего?
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[3]: Передача ссылок в поток в частности объектов класс CF
От: Patalog Россия  
Дата: 08.05.03 11:54
Оценка:
Здравствуйте, Serguei666, Вы писали:

[]

О! Давно мы с тобой не дискутировали.

P>Неужели передавать нужно именно указатель на CMyView?


S>Ну в общем, думаю да.


Почему? Из контекста топика я этого не вижу. У тебя есть какие-то дополнительные сведения от автора?

S>То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).


Вопрос скорее философский. Реальность данная мне в ощещениях говорит обратное.

S>Это же сколько доп. действий вы предлагаете:

S>1. Создать структуру

Действительно трудоемко.

S>2. Отследить, чтобы после вызова "new my_transfer_data" не забылось "delete"


А delete никогда не надо забывать вызывать. Обычно я делаю так: в потоке копирую данные в локальный для потока объект, а указателю делаю delete.
Или передаю в std::auto_ptr.
Ежели конечно, поток не возвращает данные в зад.

S>3. Скопировать данные из view в структуру


Да. Однозначно. Особенно если биты руками носить. Или в двоичном коде писать. Давай уж более конструктивно, а то детский сад какой-то.

S>4. Возможно, поддерживать копии данных в структуре в "up-to-date" состоянии (проще говоря, обновлять их)


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

S>5. Скопировать данные из структуры обратно во view


См. п.3

S>А все ради чего?


В концепции. Вьюшка — это вьюшка. Класс инкапсулирующий представление данных. И ничего более. Для какой-либо обработки нужно использовать другой класс (тот же CDocument, например).
Будь добр, приведи пример обоснованной передачи указателья на представление в другой поток.
Почетный кавалер ордена Совка.
Re[4]: Передача ссылок в поток в частности объектов класс CF
От: Serguei666 Беларусь  
Дата: 08.05.03 16:18
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Неужели передавать нужно именно указатель на CMyView?

S>Ну в общем, думаю да.
P>Почему? Из контекста топика я этого не вижу. У тебя есть какие-то дополнительные сведения от автора?
Доп. сведений нет. Я полагаю, если автор передает View, значит, так надо

S>То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).

P>Вопрос скорее философский. Реальность данная мне в ощещениях говорит обратное.
Т.е. вы ощущаете, что чем больше строк, тем меньше ошибок? Завидую.

S>Это же сколько доп. действий вы предлагаете:

S>1. Создать структуру
P> Действительно трудоемко.
S>2. Отследить, чтобы после вызова "new my_transfer_data" не забылось "delete"
P>А delete никогда не надо забывать вызывать. Обычно я делаю так: в потоке копирую данные в локальный для потока объект, а указателю делаю delete.
P>Или передаю в std::auto_ptr.
P>Ежели конечно, поток не возвращает данные в зад.
S>3. Скопировать данные из view в структуру
P>Да. Однозначно. Особенно если биты руками носить. Или в двоичном коде писать. Давай уж более конструктивно, а то детский сад какой-то.
Даже в виде C кода — надо написать кучи присваиваний. И самое главное, не забывать к этой куче добавлять строки по мере добавления новных переменных в структуру

S>4. Возможно, поддерживать копии данных в структуре в "up-to-date" состоянии (проще говоря, обновлять их)

P>Не сложнее, чем обеспечивать синхронизацию тех же данных в случае передачи указателя на вьюшку.

Синхронизацию по любому делать придется. А копирование — лишний код.

S>5. Скопировать данные из структуры обратно во view

P>См. п.3

S>А все ради чего?


P>В концепции. Вьюшка — это вьюшка. Класс инкапсулирующий представление данных. И ничего более. Для какой-либо обработки нужно использовать другой класс (тот же CDocument, например).


Не спорю. Только цепочку создать может понадобится и для вьюшки персонально.
Пример — у вас есть задача отобразить много точек (тысяч 30, звездное небо, например), данные, конечно в документе хранятся. Но вот их представление на экране зависит от Zoom фактора в данном view. T.e. на два разных view — два разных неравных в общем случае zoom фактора. Каждый view хранит экранные координаты точек, полный их набор. Пересчет занимает много времени, секунд 10-20 (например, если зависимость экранных координат от реальных нелинейная) и производится всякий раз, когда меняется zoom. Поэтому и может понадобится создавать цепочка (thread) для view, чтобы пользователь не скучал во время пересчета, глядя на белый экран. И указатель на view передается, вместо того, чтобы копировать весь массив точек туда/обратно.

P>Будь добр, приведи пример обоснованной передачи указателья на представление в другой поток.

См. выше.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[2]: Сорри, сорвалось
От: Pats Россия  
Дата: 09.05.03 07:05
Оценка:
Здравствуйте, Serguei666, Вы писали:

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


P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);
P>, но она не увенчалась успехом.
S>Вы бы подрнее писали, что знанит "не увенчалась успехом". Хотя бы на каком этапе — компиляции или исполненния — т.е. ваш код не откомпилировался или программа крэшанулась.

S>Вам же к уазателю привести надо. Значит

S>CMyView* parp=(CMyView*)par;

P>И вообще как можно передавать указатели на объекты в потоки.


S>Вы все правильно делаете. Так и надо


Извините, Я не выспавшийся был и жутко тупил. Только придя на работу, где мне собсно и надо было передать ссылку в поток я понял что всего-лишь далее после присваивания продолжал использовать переменную par. Биг сорри, так всех запутал. Даже как-то странно и ссылку сумел правильно получить и поток запустил а на какой-то ерунде прото повис-ступил. Но всё равно всем спасибо, что откликнулись.
Искренне ваш.
Re[5]: Передача ссылок в поток в частности объектов класс CF
От: Patalog Россия  
Дата: 12.05.03 12:06
Оценка:
Здравствуйте, Serguei666, Вы писали:

[]

P>Неужели передавать нужно именно указатель на CMyView?


S>Ну в общем, думаю да.


P>Почему? Из контекста топика я этого не вижу. У тебя есть какие-то дополнительные сведения от автора?


S>Доп. сведений нет. Я полагаю, если автор передает View, значит, так надо


Лично я прдположил несколько некорректную архитектуру приложения, на что и обратил внимание. Хотя конечно, если надо — значит надо.

S>То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).


P>Вопрос скорее философский. Реальность данная мне в ощещениях говорит обратное.


S>Т.е. вы ощущаете, что чем больше строк, тем меньше ошибок? Завидую.


При чем tyt строки? Я ощущуаю, что передавать в поток указатель на CView еще более небезопасно и черевато граблями. Все.

[]

P>В концепции. Вьюшка — это вьюшка. Класс инкапсулирующий представление данных. И ничего более. Для какой-либо обработки нужно использовать другой класс (тот же CDocument, например).


S>Не спорю. Только цепочку создать может понадобится и для вьюшки персонально.

S>Пример — у вас есть задача отобразить много точек (тысяч 30, звездное небо, например), данные, конечно в документе хранятся. Но вот их представление на экране зависит от Zoom фактора в данном view. T.e. на два разных view — два разных неравных в общем случае zoom фактора. Каждый view хранит экранные координаты точек, полный их набор. Пересчет занимает много времени, секунд 10-20 (например, если зависимость экранных координат от реальных нелинейная) и производится всякий раз, когда меняется zoom. Поэтому и может понадобится создавать цепочка (thread) для view, чтобы пользователь не скучал во время пересчета, глядя на белый экран. И указатель на view передается, вместо того, чтобы копировать весь массив точек туда/обратно.

Хм, в упор не вижу в этом случае потребности передавать в поток указатель на класс, дело которого лишь представление данных. Вижу потребность хранить экранные координаты не во view, а в более другом, подходящем для этого классе, в коем и производить пересчет.
В view поставить одну из WaitForXXX и наслаждаться.
Этак можн во view и работу с файлами запихать, и еще много чего. Никто не мешает ведь...
Почетный кавалер ордена Совка.
Re[6]: Передача ссылок в поток в частности объектов класс CF
От: Serguei666 Беларусь  
Дата: 12.05.03 13:10
Оценка:
Здравствуйте, Patalog, Вы писали:

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


P>[]


P>Неужели передавать нужно именно указатель на CMyView?


S>Ну в общем, думаю да.


P>Почему? Из контекста топика я этого не вижу. У тебя есть какие-то дополнительные сведения от автора?


S>Доп. сведений нет. Я полагаю, если автор передает View, значит, так надо


P>Лично я прдположил несколько некорректную архитектуру приложения, на что и обратил внимание. Хотя конечно, если надо — значит надо.


S>То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).


P>Вопрос скорее философский. Реальность данная мне в ощещениях говорит обратное.


S>Т.е. вы ощущаете, что чем больше строк, тем меньше ошибок? Завидую.


P>При чем tyt строки? Я ощущуаю, что передавать в поток указатель на CView еще более небезопасно и черевато граблями. Все.


В чем же небезопасность? Что может быть не так?


P>[]


P>В концепции. Вьюшка — это вьюшка. Класс инкапсулирующий представление данных. И ничего более. Для какой-либо обработки нужно использовать другой класс (тот же CDocument, например).


S>Не спорю. Только цепочку создать может понадобится и для вьюшки персонально.

S>Пример — у вас есть задача отобразить много точек (тысяч 30, звездное небо, например), данные, конечно в документе хранятся. Но вот их представление на экране зависит от Zoom фактора в данном view. T.e. на два разных view — два разных неравных в общем случае zoom фактора. Каждый view хранит экранные координаты точек, полный их набор. Пересчет занимает много времени, секунд 10-20 (например, если зависимость экранных координат от реальных нелинейная) и производится всякий раз, когда меняется zoom. Поэтому и может понадобится создавать цепочка (thread) для view, чтобы пользователь не скучал во время пересчета, глядя на белый экран. И указатель на view передается, вместо того, чтобы копировать весь массив точек туда/обратно.

P>Хм, в упор не вижу в этом случае потребности передавать в поток указатель на класс, дело которого лишь представление данных. Вижу потребность хранить экранные координаты не во view, а в более другом, подходящем для этого классе, в коем и производить пересчет.


А это зачем? Не вижу никаких оснований делать это.
Кстати, правила, которым я следую, таковы:
1. Если переменная используется только один раз, то она не заводится.
2. Если функция вызывается только один из одного места, она не создается
3. Если класс используеатся только в одном месте (как вы в данном случае предлагаете), то он не создается


P>В view поставить одну из WaitForXXX и наслаждаться.

P>Этак можн во view и работу с файлами запихать, и еще много чего. Никто не мешает ведь...

Я этого не прадлагал. View должно заниматься своим делом. Пересчет данных
для показа считаю одним из таких дел, работу с файлами — нет
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[7]: Передача ссылок в поток в частности объектов класс CF
От: Patalog Россия  
Дата: 13.05.03 08:13
Оценка:
Здравствуйте, Serguei666, Вы писали:

[]

P>При чем tyt строки? Я ощущуаю, что передавать в поток указатель на CView еще более небезопасно и черевато граблями. Все.


S>В чем же небезопасность? Что может быть не так?


Ну, например, многочисленные грабли с Dead Lock'ами вызванными безобидными с виду функциями класса CWnd, которые, как выясняется потом, есть простые обертки для SendMessage. Можно конечно сказать, что на эти распросьраненные грабли наступают только ламеры, но некоторое количесто подобных вопросов в эхах, да и tyt, говорит что таки лучше, когда это делается явно, как то — имеем HWND, имеем SendMessage и имеем WaitForXXXX, тогда эти ошибки ловить таки легче. Это во-первых. Во вторых, таки MFC в данном случае не thread-safe.

[]

S>А это зачем? Не вижу никаких оснований делать это.

S>Кстати, правила, которым я следую, таковы:
S>1. Если переменная используется только один раз, то она не заводится.
S>2. Если функция вызывается только один из одного места, она не создается
S>3. Если класс используеатся только в одном месте (как вы в данном случае предлагаете), то он не создается

Это _твои_ правила. Я привел _свои_ соображения. Будешь таки спорить что твоя пиписка длиннее?

P>В view поставить одну из WaitForXXX и наслаждаться.

P>Этак можн во view и работу с файлами запихать, и еще много чего. Никто не мешает ведь...

S>Я этого не прадлагал. View должно заниматься своим делом. Пересчет данных

S>для показа считаю одним из таких дел, работу с файлами — нет

А я считаю, что пересчет данных таки тоже не дело вьюшки. Точка. Может проидем в "Философию", чтобы таки дать волю флейму?

Кстати, твой пример с вьюшкой однозначно надуман. Не бывает таких точек, пересчет которых занимает 10-20 сек. Если это конечно не моделирование какой-нибудь ядерной реакции. Можно однозначно предположить, что нехрен пересчитывать столько времени _все_ точки, а достаточно пересчитать только те, которые попадают в экран.
Почетный кавалер ордена Совка.
Re[8]: Передача ссылок в поток в частности объектов класс CF
От: Serguei666 Беларусь  
Дата: 13.05.03 14:57
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Ну, например, многочисленные грабли с Dead Lock'ами вызванными безобидными с виду функциями класса CWnd, которые, как выясняется потом, есть простые обертки для SendMessage. Можно конечно сказать, что на эти распросьраненные грабли наступают только ламеры, но некоторое количесто подобных вопросов в эхах, да и tyt, говорит что таки лучше, когда это делается явно, как то — имеем HWND, имеем SendMessage и имеем WaitForXXXX, тогда эти ошибки ловить таки легче. Это во-первых. Во вторых, таки MFC в данном случае не thread-safe.


Ну так легкой жизни никто ведь и не обещал, не так ли?
Тот, кто за такое берется, должен ясно представлять себе, что MFC не thread-safe и многое надо делать самому. И создание нового класса вас от необходимости это делать не избавит.


S>А это зачем? Не вижу никаких оснований делать это.

S>Кстати, правила, которым я следую, таковы:
S>1. Если переменная используется только один раз, то она не заводится.
S>2. Если функция вызывается только один из одного места, она не создается
S>3. Если класс используеатся только в одном месте (как вы в данном случае предлагаете), то он не создается

P>Это _твои_ правила. Я привел _свои_ соображения.

Так вся наша беседа — это приведение соображений. Вы мне — своих, я вам — моих. Причем я никому ничего не навязываю. Просто говорю, как делаю я. И за вами остается право выбора — взять совет на вооружение или нет. Тоже самое право я оставляю и за собой.

P>Будешь таки спорить что твоя пиписка длиннее?

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

P>А я считаю, что пересчет данных таки тоже не дело вьюшки. Точка.

Это я понял. Хотелось бы выяснить, почему вы так считаете.

P>Может проидем в "Философию", чтобы таки дать волю флейму?

Нет. Или здесь, или тогда закончим. Я не хочу еще и в "Философию" ходить. "MFC" с меня хватит.

P>Кстати, твой пример с вьюшкой однозначно надуман.

Надуман, не спорю. Мне показалось, что звездное небо — хороший пример.

P>Не бывает таких точек, пересчет которых занимает 10-20 сек.


Есть многое на свете, друг Горацио, что и не снилось нашим мудрецам.
Не вижу ничего невозможного.

P>Если это конечно не моделирование какой-нибудь ядерной реакции.

По вашему получается, что кроме ядерной реакции совсем не существует больших массивов данных?
Вот вам пример не надуманный, а из жизни.
Когда бурят скважину, в нее опускают датчики и снимают показания.
Снимают каждые 10 см.
При бурении на 2 км получаем: 2,000м * 10точек/метр = 20,000 точек
Снимают, к примеру, 10 параметров (хотя бывает и 30), т.е. 20тыс. * 10 = 200тыс.
Я сам не снимал, я говорю по файлам с циферками, которые нам давали для теста.
Итого, имеем 200тыс точек. К тому же пользователь хочет логарифмическую шкалу, к тому же нефтяные компании большие и неповоротливые и не обеспечивают всех Пентиумами наираспоследней модели.
Короче, пересчет занимает время, и время значительное. Не 20 сек., конечно, но 5сек. вполне бывает.

P>Можно однозначно предположить, что нехрен пересчитывать столько времени _все_ точки, а достаточно пересчитать только те, которые попадают в экран.

Все правильно. Однако если установки пользователи таковы, что на экран попадают ВСЕ точки (а такие установки ему позволено сделать), то мы возвращаемся к необходимости пересчета большего количества координат.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re: Передача ссылок в поток в частности объектов класс CForm
От: dandy  
Дата: 14.05.03 06:52
Оценка:
Здравствуйте, Pats, Вы писали:

P>Господа кто-ньть знает как в поток передать указатель на объект класса CFormView. Согласно MSDN-у указатель на объект я получаю с помощью функции:


P> CMyView * CMyView::GetView()

P> {
P> CMDIChildWnd * pChild =
P> ((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();

P> if ( !pChild )

P> return NULL;

P> CView * pView = pChild->GetActiveView();


P> if ( !pView )

P> return NULL;

P> // Fail if view is of wrong kind

P> if ( ! pView->IsKindOf( RUNTIME_CLASS(CMyView) ) )
P> return NULL;

P> return (CMyView *) pView;

P> }

P>Затем передаю его в парамметрах потока:


P>CMyView *mon = GetView();


P>HANDLE wrkThr=CreateThread(0, 0, unpack, (CMyView*)mon, 0, &wrkId);



P>Функция потока выглядит следующим образом:


P>DWORD WINAPI unpack(void* par)

P>{

P> ........


P>return 0;


P>}


P>Как далее в функции потока преобразовать число принятое в парамметрах(par)

P>в класс CMyView?

P>Была такая попытка:


P> CMyView* parp=(CMyView)par;

P> CMyView* ppar=reinterpret_cast<CMyView>(*par);

P>, но она не увенчалась успехом.


P>И вообще как можно передавать указатели на объекты в потоки.


dandy>

Вообще — то микрософт категорически не рекомендует передавать в
какой — либо другой поток указатели на обьекты классов, производных
от CWnd, а буде такая нужда возникает, то рекомендуется передавать
в этот поток не CSomeClass * , а hWnd оконной процедуры, через которую
можно этот указатель вытащить (Потом нужно естественно написать CSomeWindowClass * p = (CSomeWindowClass *)CWnd::FromHandle(hWnd).
Кроме того, далеко не все МФЦэшные функции через этот самый указатель можно будет вызывать, опять же грабли. Так что...
А вообще — то, если окно уже к тому моменту создано, то указатель на него можно получить точно как у Вас написано и из другого потока.
А самое правильное, как мне кажется, это вспомнить про функцию
SendMesssage(HWND, UINT, WPARAM, LPARAM)...
Хотя писать придется побольше!
Re[9]: Передача ссылок в поток в частности объектов класс CF
От: Patalog Россия  
Дата: 14.05.03 07:18
Оценка:
Здравствуйте, Serguei666, Вы писали:

[]

P>Ну, например, многочисленные грабли с Dead Lock'ами вызванными безобидными с виду функциями класса CWnd, которые, как выясняется потом, есть простые обертки для SendMessage. Можно конечно сказать, что на эти распросьраненные грабли наступают только ламеры, но некоторое количесто подобных вопросов в эхах, да и tyt, говорит что таки лучше, когда это делается явно, как то — имеем HWND, имеем SendMessage и имеем WaitForXXXX, тогда эти ошибки ловить таки легче. Это во-первых. Во вторых, таки MFC в данном случае не thread-safe.


S>Ну так легкой жизни никто ведь и не обещал, не так ли?


То же самое могу ответить на

То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).



S>Тот, кто за такое берется, должен ясно представлять себе, что MFC не thread-safe и многое надо делать самому. И создание нового класса вас от необходимости это делать не избавит.


Не избавит касательно "MFC не thread-safe". Но работа с Send'ами и Wait'ами будет прозрачнее. Будешь спорить?

[]

P>А я считаю, что пересчет данных таки тоже не дело вьюшки. Точка.


S>Это я понял. Хотелось бы выяснить, почему вы так считаете.


Как я уже говорил — по идеологическим причинам. Я тоже не сторонник заводить на каждый чих отдельный класс, но разнести представление данных и их обработку считаю обоснованным. Мой подход в данном случае примерно следующий — CView — это простой wrapper для HWND и только.

[]

P>Не бывает таких точек, пересчет которых занимает 10-20 сек.


S>

S>Есть многое на свете, друг Горацио, что и не снилось нашим мудрецам.
S>Не вижу ничего невозможного.

1. "Если постулировать бесконечность можно предположить что угодно".
2. "С дуру можно и хер сломать"

P>Если это конечно не моделирование какой-нибудь ядерной реакции.


S>По вашему получается, что кроме ядерной реакции совсем не существует больших массивов данных?


Существуют, существуют. Не придирайся по пустякам.

[]

S>Все правильно. Однако если установки пользователи таковы, что на экран попадают ВСЕ точки (а такие установки ему позволено сделать), то мы возвращаемся к необходимости пересчета большего количества координат.


Слабо себе представляю 200.000 точек (несущих семантическую ценность именно как отдельный объект. Не линий или там прямоугольников, ибо в таком случае их можно аппроксимироват и что_там_еще_у_нас_есть_в_арсенале) на экране 800*600 (это с учетом

не обеспечивают всех Пентиумами наираспоследней модели

, что дает возможность предположить, что мониторами "наираспоследней" тоже не обеспечивают).

Но все это тоже, придирки по пустякам, уже с моей стороны.
Давай к сути вопроса.
Смею предположить, что этот "большой массив данных" храниться таки в динамической памяти.
Почему бы в таком случае не передать в поток указатель на него?
Почетный кавалер ордена Совка.
Re[10]: Передача ссылок в поток в частности объектов класс C
От: Serguei666 Беларусь  
Дата: 14.05.03 13:22
Оценка:
Здравствуйте, Patalog, Вы писали:

S>Ну так легкой жизни никто ведь и не обещал, не так ли?

P>То же самое могу ответить на
P>

P>То, что вы предлагаете, гораздо более трудоемко и небезопасно (в смысле, есть где ошибок наделать).

Можете, но это не то же самое. То, что жизнь нелегка, не отменяет необходимости упрощать ее где только возможно.


S>Тот, кто за такое берется, должен ясно представлять себе, что MFC не thread-safe и многое надо делать самому. И создание нового класса вас от необходимости это делать не избавит.


P>Не избавит касательно "MFC не thread-safe". Но работа с Send'ами и Wait'ами будет прозрачнее. Будешь спорить?

Ну, в общем, буду.
Если заведете отдельный класс, то работа с Send'ами вообще отменяется. Ну а как облегчится работа с Wait'ами?


P>А я считаю, что пересчет данных таки тоже не дело вьюшки. Точка.

S>Это я понял. Хотелось бы выяснить, почему вы так считаете.
P>Как я уже говорил — по идеологическим причинам. Я тоже не сторонник заводить на каждый чих отдельный класс, но разнести представление данных и их обработку считаю обоснованным.

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

P>Если это конечно не моделирование какой-нибудь ядерной реакции.

S>По вашему получается, что кроме ядерной реакции совсем не существует больших массивов данных?
P>Существуют, существуют. Не придирайся по пустякам.

Вы первый начали: "НЕ БЫВАЕТ таких точек, пересчет которых занимает 10-20 сек."


S>Все правильно. Однако если установки пользователи таковы, что на экран попадают ВСЕ точки (а такие установки ему позволено сделать), то мы возвращаемся к необходимости пересчета большего количества координат.


P>Слабо себе представляю 200.000 точек (несущих семантическую ценность именно как отдельный объект. Не линий или там прямоугольников, ибо в таком случае их можно аппроксимироват и что_там_еще_у_нас_есть_в_арсенале) на экране 800*600 (это с учетом

P>

P>не обеспечивают всех Пентиумами наираспоследней модели

, что дает возможность предположить, что мониторами "наираспоследней" тоже не обеспечивают).


Конечно, мы не точки показываем, а кривую, состоящую из отрезков, эти точки соединяющие.

Как пользователь просил сделать, так мы и сделали. К тому же там такие данные — для меня выглядят как белый шум. Как такое аппроксимировать? Наш софт — не единственный, кто эти файлы с кривыми показывал. Вы нааппраксимируете — а пользователь спросит — "чего это картинка у вас не так выглядит, как в программе YYY?". Придется исправлять.

Вы же не хотите, чтобы я пытался доказать пользователю, что то, что он хочет увидеть, не имеет "семантической ценности"? Представляете, приходит к вам, к примеру, водитель такси и начинает рассказывать, что, к примеру, MFC не имеет "семантической ценности"? Что вы ему на это ответите? Может, просто вызовите другое такси?

Одно из условий разработки было "все должно хорошо выглядеть на 800х600". Я не знаю как сейчас, я уже 4 года там не работаю. У пользователей (нефтяников) в основом были ноутбуки, у которых мониторы менее мощные, чем у десктопов.

P>Но все это тоже, придирки по пустякам, уже с моей стороны.

P>Давай к сути вопроса.
P>Смею предположить, что этот "большой массив данных" храниться таки в динамической памяти.
P>Почему бы в таком случае не передать в поток указатель на него?
Надо передать указатель на массив массивов (каждая кривая — это массив точек, итого — массив кривых), надо передеаать указатель на параметры каждой кривой (мин., макс. значения шкалы, тип шкалы), надо передать данные о том, в каком режиме мы показываем кривые (режимов больше, чем один)
Итого имеем кучу параметров для передачи. Цепочка принимает только один параметр. Значит, надо все параметры объединять в структуру и передавать указатель на нее (то, что вы предлагаете). Я предлагаю подумать на еще один шаг вперед — зачем создавать структуру, если можно передать указатель на view? View — по сути, та же структура.
Хотите сказать 'спасибо'? Тогда поставьте оценку
Re[11]: Передача ссылок в поток в частности объектов класс C
От: Patalog Россия  
Дата: 15.05.03 10:25
Оценка:
Здравствуйте, Serguei666, Вы писали:

[]

S>Тот, кто за такое берется, должен ясно представлять себе, что MFC не thread-safe и многое надо делать самому. И создание нового класса вас от необходимости это делать не избавит.


P>Не избавит касательно "MFC не thread-safe". Но работа с Send'ами и Wait'ами будет прозрачнее. Будешь спорить?


S>Ну, в общем, буду.

S>Если заведете отдельный класс, то работа с Send'ами вообще отменяется. Ну а как облегчится работа с Wait'ами?

Что значит отменяется? Поясни свою мысль.
Как раз таки я не предлагаю городить очередную обертку вокруг HWND, а использовать as-is. Чтобы и Send'ы и Wait'ы лежали "на поверхности".
Чтобы не быть голословным, посмотри например вот этот классический случай
Автор: Hrum
Дата: 14.09.02


[]

S>А считаю пересчет координат частью представления данных, никак не обработкой. Ведь экранные координаты нужны только для показа данных. Зачем же пересчет отделять от показа?


Я считаю так, вы — этак. На этом закончим.

P>Если это конечно не моделирование какой-нибудь ядерной реакции.

S>По вашему получается, что кроме ядерной реакции совсем не существует больших массивов данных?
P>Существуют, существуют. Не придирайся по пустякам.

S>Вы первый начали: "НЕ БЫВАЕТ таких точек, пересчет которых занимает 10-20 сек."


Т.е. в твоем понимании фразамы "не существует больших массивов данных" и "НЕ БЫВАЕТ таких точек, пересчет которых занимает 10-20 сек."
тождественны? Браво.

S>Все правильно. Однако если установки пользователи таковы, что на экран попадают ВСЕ точки (а такие установки ему позволено сделать), то мы возвращаемся к необходимости пересчета большего количества координат.


P>Слабо себе представляю 200.000 точек (несущих семантическую ценность именно как отдельный объект. Не линий или там прямоугольников, ибо в таком случае их можно аппроксимироват и что_там_еще_у_нас_есть_в_арсенале) на экране 800*600 (это с учетом

P>

P>не обеспечивают всех Пентиумами наираспоследней модели

, что дает возможность предположить, что мониторами "наираспоследней" тоже не обеспечивают).


S>Конечно, мы не точки показываем, а кривую, состоящую из отрезков, эти точки соединяющие.


Ну вот, уже лучше. Т.е. таки отрезки наличествуют. Позволю себе предположить, что существуют и прямоугольники etc.

S>Как пользователь просил сделать, так мы и сделали. К тому же там такие данные — для меня выглядят как белый шум. Как такое аппроксимировать? Наш софт — не единственный, кто эти файлы с кривыми показывал. Вы нааппраксимируете — а пользователь спросит — "чего это картинка у вас не так выглядит, как в программе YYY?". Придется исправлять.


Так файл таки с кривыми или таки с точками? Разницу между векторным и растровым форматом объяснять нужно?
Или у вас юзеры в состоянии отличить линию, нарисованную "сементически значимыми" точками от прямой, началом и концом которй являются "значимые" точки, а остальные нарисованы графической подсистемой и соответ. для расчета которых драгоценное процессорное время не затрачивается?
Вы когда там у себя окружность на экране рисуете, тоже все пиксели сами считаете?

S>Вы же не хотите, чтобы я пытался доказать пользователю, что то, что он хочет увидеть, не имеет "семантической ценности"? Представляете, приходит к вам, к примеру, водитель такси и начинает рассказывать, что, к примеру, MFC не имеет "семантической ценности"? Что вы ему на это ответите? Может, просто вызовите другое такси?


Не передергивай. Я говорил о том, что при разрешении 800*600 эти 200.000 точек будут на экране видны как каждый второй пиксель. Сильно сомневаюсь полезности подобной информации. Хотя может у вас там уникумы сидят...
Или у вас точки меняют свое расположение друг относительно друга в зависимости от коэфициента увеличения (т.е. при 20:1 точки были семантически на одной прямой, а при 1:1 оказались в разных концах экрана)?

[]

S>Итого имеем кучу параметров для передачи. Цепочка принимает только один параметр. Значит, надо все параметры объединять в структуру и передавать указатель на нее (то, что вы предлагаете). Я предлагаю подумать на еще один шаг вперед — зачем создавать структуру, если можно передать указатель на view? View — по сути, та же структура.


Как раз таки не по сути, а только в силу языковых конструкций языка реализации. По сути — View это в первую очередь обертка представляющая собой окно, в системном смысле этого слова.

ЗЫ Заканчиваем, ибо судя по всему этот спор не имеет реальной ценности. Хотя мне сильно интересна такая ваша специфика, когда на экране информативна каждая из 200.000 точек. ЕСли не лень, напиши в мыло.
Почетный кавалер ордена Совка.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.