Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2002.02.14;
Скачать: [xml.tar.bz2];

Вниз

Потоки и окна   Найти похожие ветки 

 
Cobalt   (2001-12-11 02:37) [0]

Создаю поток. Хочу в нём создать окно, и вспомнил, как где-то читал, что у каждого потока должна быть своя очередь сообщений, если он создаёт окно.

Такой вот вопрос. Как соотносятся потоки и Application?
Ведь если попытаться создать форму в потоке <c>Application.CreateForm(TForm1,Form1);</c>, то ...

Это надо вво-1)первых синхронизировать, а это чревато тем, что вместо многопоточности мы получаем сплошную синхронизацию

А во-2)вторых, если не синхронизировать(допустим, не произойдёт AV), то куда будут приходить сообщения для формы? В основной поток(MainForm и всё такое), или туда, где его породили?

Хотя можно просто <c>Form1.Create(nil);</c>
Но тогда опять возникает вопрос об обработке сообщений - где/как делать цикл приёма - трансляции сообщений?


 
Digitman   (2001-12-11 15:33) [1]

>Cobalt
Видимо, ты не понимаешь (или не совсем понимаешь) разницы между системным объектом - окном Windows и VCL-объектом - формой Делфи.
Объект-окно Windows можно создать и в доп.потоке процесса, но обработка сообщений, посылаемых этому окну, должна и будет производиться в осн.потоке процесса.
Объект-форму нельзя создавать в доп.потоке, код вызова конструктора формы должен быть синхрогизирован любым доступным способом с осн.потоком процесса. При этом доп.поток также не сможет получать и обрабатывать сообщения окну, на котором базируется созданная доп.потоком формы.
Здесь нужно понять одно : очереди сообщений различных потоков никак не связаны друг с другом, существуют в системе параллельно и независимо друг от друга, и каждый поток сам ответственен за диспетчеризацию сообщений, посланных именно ему.
VCLобъект-форма наследует класс TWinControl, в котором Борландом уже инкапсулированы ф-ции ожидания, приема и диспетчеризации сообщений, адресованных окну формы. Т.е., заботиться о создании диспетчера очереди оконных сообщений при работе с формой не надо - он автоматически создается в реализации класса TWinControl.
Системный же объект-thread (тот самый, созданием и управлением которым "заведует" класс TThread) обязан сам контролировать в процессе своей работы очередь адресованных ему сообщений. С т.з. класса TThread это значит, что в коде его метода Execute должны присутствовать какие-либо вызовы API, предназначенные для работы с очередью сообщений потоку. Это могут быть вызовы из следующего ряда : GetMessage, PeekMessage, WaitMessage, MsgWaitForSingleObject, MsgWaitForMultipleObjects. Каждый из этих вызовов тем или иным образом обращается к системной очереди сообщений, созданной индивидуально для тек.доп.потока. В зависимости от конкретного вызова взаимодействие происходит по-разному : можно просто контролировать факт наличия сообщения в очереди, а можно и выбирать очередные сообщения из очереди (с ожиданием или без, с удалением из очереди или без оного - вариантов много). Здесь надо особо отметить, что ОС не создает очереди сообщений доп.потока безусловно (просто - по факту его старта). Очередь сообщений будет создана только при первом вызове одногq из вышеуказанных API-ф-ций. Поэтому сообщения, посланные потоку в период между его фактическим стартом и первым же вызовом им одной из вышеуказанных API-ф-ций, просто-напросто "пропадут" - будут посланы в "пустоту", как адресованные несуществующей еще в момент посылки сообщения очереди. Именно поэтому указанный период времени следует сокращать до минимума, и именно поэтому во многих реализациях метода Execute различных классов-наследников TThread одной из первых инструкций стоит инструкция PeekMessage, призванная создать очередь сообщений потока.

Создавать объект-форму в доп.потоке в подавляющем большинстве случаем просто бессмысленно и неоправданно, т.к. доп.потоки призваны реализовать параллельное функционирование непрерывных/циклических и длительных по времени вычислений. Форма же, как правило, "простаивает" в ожидании событий ввода/вывода, т.е. работает синхронно (есть ли смысл создавать и интенсивно работать с синхронными объектами в контексте асинхронных по сути объектов ?)


 
y-soft   (2001-12-11 20:29) [2]

Небольшое дополнение:

Как пишет Рихтер, в Explorer"е каждое новое окно создается в отдельном потоке. Так что иногда и это бывает оправдано...


 
Cobalt   (2001-12-13 07:37) [3]

Большое спасибо!


 
paul_shmakov   (2001-12-15 00:13) [4]

2 digitman:
"Объект-окно Windows можно создать и в доп.потоке процесса, но обработка сообщений, посылаемых этому окну, должна и будет производиться в осн.потоке процесса.
Объект-форму нельзя создавать в доп.потоке, код вызова конструктора формы должен быть синхрогизирован любым доступным способом с осн.потоком процесса. При этом доп.поток также не сможет получать и обрабатывать сообщения окну, на котором базируется созданная доп.потоком формы."


не согласен. если поток создает окно, то в нем создается очередь сообщений, и поток самостоятельно обрабатывает сообщения, посланные этому окну. а не главный поток приложения.
с формами тоже самое. простой пример: создайте простое приложение, объект TThread и еще одну форму, которая будет создаваться и показываться из тела метода Execute потока.
далее у этой формы в обработчике какого-либо события (например, OnShow) поставить вызов GetCurrentThreadId и вывести возвращенное значение.
не буду пытать - значения будет равно иентификатору именно этого дополнительного потока.


 
Digitman   (2001-12-17 09:47) [5]

>paul_shmakov
Ок. Согласен. Более корректно было бы сказать так :

"Объект-окно Windows можно создать и в доп.потоке процесса, но обработка сообщений, посылаемых этому окну, должна производиться в осн.потоке процесса, если созданное окно - визуальное, и при обработке его сообщений должен осуществляться доступ к разделяемым ресурсам системы (в 1-ю очередь, GDI-вызовы API).

Объект-форму (как объект, инкапсулирующий управление классом виз.окна) нельзя безошибочно создавать в доп.потоке (обязательно возникнет исключение канвы); код вызова конструктора формы должен быть синхронизирован любым доступным способом с осн.потоком процесса.





Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.02.14;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.004 c
1-42717
Welder
2002-01-30 11:21
2002.02.14
TdrawGrid


6-42816
Knish
2001-11-24 18:53
2002.02.14
А как можно сделать, чтоб программа запускалась только на сервере?


14-42855
Snake
2001-12-24 18:03
2002.02.14
Администрирование Win2000


1-42793
raspirator
2002-01-30 21:20
2002.02.14
Как конвертировать!!!


1-42765
kingdom
2002-01-30 14:40
2002.02.14
Нужен TShape нестандарной формы, как это сделать?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский