Форум: "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