Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 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).

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





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




Наверх





Память: 0.74 MB
Время: 0.016 c
3-42644           Hawk2                 2002-01-16 17:14  2002.02.14  
Преобразование типов.


1-42805           Анатолий              2002-02-01 07:11  2002.02.14  
SaveDialog


4-42894           denis_ka              2001-12-17 23:37  2002.02.14  
Использование статических DLL из EXE файла


3-42672           RealyGrey             2002-01-15 13:21  2002.02.14  
Немогу законнектиться в оракловскую базу. Мистика!!


3-42676           Georg                 2002-01-18 13:27  2002.02.14  
Построение индексов