Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
|
Может быть я поступал не слишком оптимально, но я как... 26.08.09 11:08 Число просмотров: 2944
Автор: Heller <Heller> Статус: Elderman Отредактировано 26.08.09 11:08 Количество правок: 1
|
Может быть я поступал не слишком оптимально, но я как правило в таких случаях вызывал глобальную функцию, аргументом которой передавал указатель на объект. А уже потом от этого указателя вызывал метод, который хочу иметь как рабочую функцию треда.
|
<programming>
|
[C++] Может ли ThreadProc быть мембером класса, запускающего поток? 26.08.09 10:47
Автор: Zef <Alloo Zef> Статус: Elderman
|
И увидит ли она переменные и методы класса?
Никогда так на делал - ThreadProc глобальная, и все. А тут тред запускается из диалога и должен непрерывно печатать результаты вычислений в него же, при этом, на экране непрерывно должен висеть МесседжБокс с кнопкой останова вычислений.
|
|
Конечно может 05.09.09 05:03
Автор: void <Grebnev Valery> Статус: Elderman
|
|
|
In-proc COM сервер? 26.08.09 19:57
Автор: Den <Денис Т.> Статус: The Elderman
|
|
| |
Нет. Типа, легальный кейлоггер. 27.08.09 09:20
Автор: Zef <Alloo Zef> Статус: Elderman
|
Я же писал: некий девайс определяется, как клава и сливает данные. Задача - принять данные не дав юзеру нажать на клаву или заблокировав ее. Все это должно быть в 1м ехе без драйверов и длл.
Пока вариант 1. Проблема в том, что передача может завершиться признаком конца, а может и зависнуть. Значит, все время должно висеть сисмодальное окно с кнопкой останова и предупреждением, чтобы не трогали клаву.
Счас все работает так: старт приема запускает поток в котором в цикле крутится GetAsyncKeyState и выводит сисмод диалог. Если кликнули стоп - устанавливается флаг "остановить". Если передача завершилась нормально, поток отправляет сисмод диалогу ONCANCEL.
|
| | |
Callback функции не могут быть мемберами классов 27.08.09 13:29
Автор: Den <Денис Т.> Статус: The Elderman
|
Но ты можешь хранить в памяти таблицу соответствия хенлов процессов и ссылок на экземпляры объектов, функции-мемберы которых ты можешь вызывать из callback функции.
|
| | | |
WndProc - может, а другие - нет? 27.08.09 16:35
Автор: Zef <Alloo Zef> Статус: Elderman
|
|
| | | | | |
Пардон, ее, родимую! 27.08.09 18:07
Автор: Zef <Alloo Zef> Статус: Elderman
|
> Может все-таки ты имеешь ввиду эту функцию?: > http://msdn.microsoft.com/en-us/library/ms633573(VS.85).asp > x > > Так она не может быть функцией-членом класса. Ну, так все равно, механизм ее использования есть - она же может вызывать ф-ции члены - обработчики сообщений. Если поток с очередью сообщений - все так же, если без - сделали бы вызов единственной ф-ции, которую и переопределять.
|
| | | | | | |
Конечно может! 27.08.09 21:03
Автор: Den <Денис Т.> Статус: The Elderman
|
> Ну, так все равно, механизм ее использования есть - она же > может вызывать ф-ции члены - обработчики сообщений.
Конечно может!
Только сама не может быть функцией-членом класса.
Функции WinAPI оперируют хендлами и структурами, но не классами. Наследие...
> Если поток с очередью сообщений - все так же, если без - > сделали бы вызов единственной ф-ции, которую и переопределять.
Так и сделано. Есть хендл, который позволяет привязать callback функцию к конкретному "объекту" операционной системы.
|
| | | | | | |
собсно никто не мешает сделать и так 27.08.09 18:38
Автор: dl <Dmitry Leonov>
|
> Ну, так все равно, механизм ее использования есть - она же > может вызывать ф-ции члены - обработчики сообщений. Если > поток с очередью сообщений - все так же, если без - сделали > бы вызов единственной ф-ции, которую и переопределять.
Переопредели CWinThread::InitInstance без создания окна, возвращающий FALSE, и будет ровно такой же эффект. Только это геморрой ради геморроя, лепить класс ради вызова единственной функции.
|
|
нет 26.08.09 11:09
Автор: dl <Dmitry Leonov> Отредактировано 26.08.09 11:10 Количество правок: 1
|
Не считая варианта static member, что не считается. Хотя никто не мешает передать в поток указатель на объект и первой/единственной строчкой потоковой функции дернуть через него нормальную функцию (а если оформить это макросом, то и совсем незаметно получится).
> И увидит ли она переменные и методы класса? > Никогда так на делал - ThreadProc глобальная, и все. А тут > тред запускается из диалога и должен непрерывно печатать > результаты вычислений в него же, при этом, на экране > непрерывно должен висеть МесседжБокс с кнопкой останова > вычислений.
Кстати, если речь о MFC, то рабочие потоки с интерфейсом с большими нюансами взаимодействуют, через шаг нарываясь на ассерты. Может быть, стоит рассмотреть вариант с интерфейсным потоком (который потомок CWinThread).
|
| |
Дык я CWinThread и юзаю 26.08.09 12:52
Автор: Zef <Alloo Zef> Статус: Elderman
|
Почему и не могу понять - вроде МФСевый класс, а работает через какую-то ж..., типа AfxBeginThread.
Почему нельзя было сделать так, чтобы объявил экземпляр класса, а сам поток запускал через, типа CWinThread.Start(), CWinThread.Kill() с возможностью доступа, как к публичным свойствамна ходу, так и из него - ко всем внешним переменным обычным образом?
|
| | |
там чуть хуже 26.08.09 17:05
Автор: dl <Dmitry Leonov> Отредактировано 26.08.09 17:13 Количество правок: 4
|
> Почему и не могу понять - вроде МФСевый класс, а работает > через какую-то ж..., типа AfxBeginThread. > Почему нельзя было сделать так, чтобы объявил экземпляр > класса, а сам поток запускал через, типа > CWinThread.Start(), CWinThread.Kill() с возможностью > доступа, как к публичным свойствамна ходу, так и из него - > ко всем внешним переменным обычным образом?
Если бы дали создавать самому, то нашлись бы толпы программистов, создающих этот объект в автоматической памяти или забывающих удалять объект после завершения потока при создании в динамической памяти. Так же AfxBeginThread передается объект, способный создать потоковый объект так, как ей нужно. С инициализацией его чуть хуже, но вполне можно создать поток с CREATE_SUSPENDED, проинициализировать все, что нужно, через указатель, который вернула AfxBeginThread, и разбудить поток (штатная техника, описанная в MSDN) - это если хочется избежать глобальных переменных, конечно. Ну и доступ есть как ко внешним переменным из объекта, так и к его полям, только при доступе извне нужно быть уверенным, что он в этот момент существует.
CDocument и CView ведь тоже самостоятельно не создаются из тех же соображений удобства для фреймворка.
|
| | | |
Блин, проспался - понял. 27.08.09 10:50
Автор: Zef <Alloo Zef> Статус: Elderman
|
> Ну и > доступ есть как ко внешним переменным из объекта, так и к > его полям, только при доступе извне нужно быть уверенным, > что он в этот момент существует.
Нет там никакого доступа и быть не может. Потоки в разных адресных пространствах сидят, у них тока длл общие. Меня вчера на ночь глядя переклинило, что pParam в AfxBeginThread - int, тогда, как он LPVOID. Оно там на другое место, где я случайно букву впечатал, ругалось, что не может к инту преобразовать, а я на pParam думал. Вот, я и не мог въехать, как же так - если указатель передается, как число, тада и все остальные указатели и переменные должны быть валидны, но как? Компилер сам процедуру пересчета адресов подставляет?
Поутру продрав глаза обнаружил опечатку и то, что pParam - LPVOID. В бошке прояснилось: AfxBeginThread отображает pParam в тред. Естессно, в списке параметров тада указатели передавать нельзя. Тока числа и хендлы.
|
| | | | |
Так ты используешь CreateRemoteThread ? [upd] 27.08.09 13:31
Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 27.08.09 13:42 Количество правок: 1
|
[upd]
Забудь про int в API вызовах. За редким исключением, большинство целочисленных параметров DWORD или LONG POINTER, flat'овый сегмент каждого процесса в 32-битных ОСях простирается на 3Гб виртуального адресного пространства.
|
| | | | | |
С разбегу я ее использую! 27.08.09 16:38
Автор: Zef <Alloo Zef> Статус: Elderman
|
Я же ясно написал, что GetAsyncKeyState в цикле кручу. Ну нафига мне ремоут тред в совершенно легальной читалке какого-то изредка подключаемогок компу девайса?
|
| | | | | | |
Я спросил, потому что ты написал про потоки в разных адресных пространствах. 27.08.09 17:19
Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 27.08.09 17:20 Количество правок: 1
|
|
| | | | |
А вот теперь, внимание - вопрос! (Амирул, выручай! На тебя вся надежда.) 27.08.09 12:10
Автор: Zef <Alloo Zef> Статус: Elderman
|
Когда AfxBeginThread отображает указатель блока аргументов в память потока, как она узнает резмеры этого блока? Или его размер ограничен страницей памяти? (Надо полагать, в память потока может мапится только страница целиком)
А если блок не в начале страницы?! Нигде ведь не сказано, что память под блок должна выделяться маллоком и в МСДНском примере этого нет.
Ниче не понимаю! Получается, что все потоки процесса сидят в общей памяти? Тада нахрена гиморой с передачей указателя на блок аргументов? Мелкомягкие в очередной раз хотели сделать умную рожу при идиотской игре? Или у них компилер такой умный, что несмотря на то, что я передаю указатель LPVOID, он смотрит чтобыло преобразованно к этому виду и определяет размеры, а потом размещает ЭТО в точности в начале страницы? Нереально...
|
| | | | | |
нет никакой памяти потока (не считая TLS) 27.08.09 12:13
Автор: dl <Dmitry Leonov> Отредактировано 27.08.09 12:19 Количество правок: 3
|
...но чтобы им пользоваться нужны дополнительные усилия. По умолчанию все потоки одного процесса живут в одном адресном пространстве, это азбука. Первая же строчка описания СreateThread в MSDN:
Creates a thread to execute within the virtual address space of the calling process.
> Ниче не понимаю! Получается, что все потоки процесса сидят > в общей памяти? Тада нахрена гиморой с передачей указателя > на блок аргументов? Мелкомягкие в очередной раз хотели > сделать умную рожу при идиотской игре?
Возможность передачи информации через параметр, а не через глобальные переменные - это идиотская игра?
|
| | | | | | |
Гибрид ежа с ужом. 27.08.09 13:08
Автор: Zef <Alloo Zef> Статус: Elderman
|
> Возможность передачи информации через параметр, а не через > глобальные переменные - это идиотская игра?
Это нормально для плейн-С чтобы передать переменный список параметров. А для МФС это - дичь пернатая. Если уж классы, то свойства и методы через точечку или стрелочку. А за создание объекта "поток" через AfxBeginThread надо отрывать гениталии! Если поток - класс, то почему его надо создавать через невесть какую ж...?
Речь не о том, что я не умею работат с потоками, я знаю, как это делается в плейн-С. Но сочиняя некую приблуду для заказчика я решил, что плейн-С, это не цивилизованно, мало ли кому чего потом переделать захочется - плейн-С никто знать не обязан. И тут я вижу, что в МФС имеется набор: каменный топор и фиберглассовое топорище... Причем, чтобы его насадить, надо еще в камне дырку самому проколупать!
Конечно, "партайгеноссе Борланд", это другая крайность, когда обертки на все случаи жизни в 10 раз больше конфетки, но дожен же быть кто-то, кто хоть немного приблизится к "золотой середине"! Почему все Мастдайство состоит из одних крайностей? Либо - крайний примитив, когда море кода приходится писать руками, либо - ради таблички в 3 строчки подымают SQL-сервер...
|
|
|