Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Атомарен ли TThread.Synchronize ?


Автор: Gershkovich 3.3.2008, 15:57
Всем привет!

Скажите может ли быть такая ситуация:

VCL поток выполняет метод А некоторое время
В этот момент другой поток вызывает метод Synchronize(B)
Т.е.  VCL поток должен выполнить метод В

Так вот вопрос : Выполнится ли метод А до конца 
или возможна ситуация когда выполнение А приостанавливается
затем выполняется В, и снова возвращается в А ?

Заранее спасибо.

Автор: Alexeis 3.3.2008, 16:15
Вот чего говорит наш великий мануал о потоках в делфи
Цитата

Ограничения Synchronize.

У метода Synchronize есть несколько недостатков, благодаря которым он подходит лишь для простых многопоточных приложений.

    * Synchronize полезен лишь при взаимодействии между рабочим потоком и основным потоком VCL.
    * Использование Synchronize подразумевает,что рабочий поток ждет, пока основной поток VCL будет в состоянии ожидания, даже когда это не так уж и необходимо.
    * Если приложение часто использует Synchronize, главный поток VCL становится "узким местом", и возникают проблемы с производительностью.
    * Если Synchronize используется для непосредственного взаимодействия двух рабочих потоков, оба они могут быть приостановлены, ожидая главный поток.
    * Synchronize может вызвать зацикливание, если главный поток VCL ожидает другие потоки.

Правда, у Synchronize есть и одно преимущество над другими механизмами синхронизации:

    * В методе, вызываемом с помощью Synchronize, может быть любой код, в том числе и потоко-небезопасный код VCL.


  Т.е. работать оно будет, но не самым эффективным образом.

Автор: Poseidon 3.3.2008, 16:15
Так, стоп! Метод Synchronize используется для безопасного вызова методов VCL внутри потоков. Т.е. если "другой поток" выполняет Synchronize(B), то B выполнится в рамках этого "другого" потока, и никак не отразится на работе потока А., т.е. А в, этом случае, выполнится до конца.

Автор: VICTAR 3.3.2008, 16:18
Насколько я знаю
Цитата(Gershkovich @  3.3.2008,  15:57 Найти цитируемый пост)
выполнение А приостанавливается
затем выполняется В, и снова возвращается в А


Автор: Poseidon 3.3.2008, 16:23
VICTAR, я вот так понял: у нас 2 потока и 2 метода. Каждый метод выполняется в своем потоке. С какого перепугу один из них будет останавливаться?  smile 

Автор: VICTAR 3.3.2008, 16:25
А я понял, что у нас один главный VCL поток и один "другой" поток.
ЗЫ я ничего не утверждаю, просто высказал свое предположение.

Автор: Gershkovich 3.3.2008, 16:28
Poseidon, насколько я понимаю Synchronize, оба метода выполняются в главном потоке
"Другой поток" просто просит главный выполнить метод В и ждет пока главный не выполнит этот метод.

VICTAR прав

Автор: Rennigth 3.3.2008, 16:35
Цитата(Poseidon @  3.3.2008,  16:23 Найти цитируемый пост)
VICTAR, я вот так понял: у нас 2 потока и 2 метода. Каждый метод выполняется в своем потоке. С какого перепугу один из них будет останавливаться?    

Assign a method to WakeMainThread before calling a thread’s Synchronize method. When you call a thread’s Synchronize method, it calls the method assigned to WakeMainThread once it has obtained a lock on the main GUI thread. This allows other threads to quickly synchronize with the GUI thread even if no events are being processed due to an idle state.

Автор: MetalFan 3.3.2008, 17:27
Alexeis же во втором посте все написал. что тут еще за гадания на кофейной гуще? )

Автор: Gershkovich 4.3.2008, 12:15
Экспериментальным путем было установлено, что ни один из методов
не прерывается.
Т.е. метод В не начнется пока не закончится А и наооборот

Автор: MetalFan 4.3.2008, 14:02
Gershkovich, это из кода VCL ясно)

Автор: dumb 4.3.2008, 14:48
запутали бедолагу. smile аж опыты вынудили проводить...

Цитата(Gershkovich @  4.3.2008,  12:15 Найти цитируемый пост)
метод В не начнется пока не закончится А и наооборот
все верно. 
еще разок, для закрепления: Synchronize просто добавляет адрес переданного ему метода в глобальный список, который проверяется главным потоком - если есть элемент, то происходит вызов процедуры(адрес которой содержится в элементе) в контексте главного потока. по окончании выполнения этой процедуры главный поток сигнализирует рабочему потоку, вызвавшему Synchronize, что можно продолжать работать.

т.е. никаких выполнений "вперемешку" нет - все происходит в контексте главного потока "в порядке общей очереди". smile

Автор: GrigorievAnton 4.3.2008, 19:50
На самом деле такая ситуация возможна, если метод A вызывает Application.ProcessMessages - Application.ProcessMesages проверяет очередь синхронизированных методов и выполняет первый из неё. Если не вызывает - то действительно в порядке общей очереди.

Автор: MetalFan 5.3.2008, 10:34
не вижу смысла вызова ProcessMessages в синхронизируемой функции. хотя что только в голову людям не придет)

Автор: Alexeis 5.3.2008, 10:55
Цитата(MetalFan @  5.3.2008,  09:34 Найти цитируемый пост)
не вижу смысла вызова ProcessMessages в синхронизируемой функции

  С таким же успехом можно досрочно выйти из критической секции или сигнализировать семафор, но это просто глупо в данной ситуации.

Автор: GrigorievAnton 5.3.2008, 11:49
Цитата(MetalFan @ 5.3.2008,  10:34)
не вижу смысла вызова ProcessMessages в синхронизируемой функции.

При чём здесь синхронизируемая функция? Я же написал - Application.ProcessMessages вызывается в методе A, а метод A - это не синхронизируемый метод, а тот метод, который в обычном порядке выполняется главной нитью. Он и не подозревает ни о какой синхронизации. Синхронизируемый метод - это B - см. самое первое сообщение

P.S. Странное впечатление от этого форума. Выглядит так, будто многие участники читают чужие сообщения через слово, пропущенную часть достраивают в меру своей фантазии , а потом отвечают на то, что есть у них в голове, но никак не в прочитанном сообщении.

Автор: dumb 5.3.2008, 12:26
экий ты суровый! не стоит делать поспешных выводов. smile

а насчет ProcessMessages: это ж такой специальный костыль, пользуя который, ты - сам себе злобный буратин с отпиленным носом.
вменяемый человек, даже если и использует его, то отдает себе отчет в том, что в данной точке он "сливает" управление, и врядли будет потом задаваться вопросом "почему у меня выполняется это, если еще не завершилось то?".

Автор: GrigorievAnton 5.3.2008, 15:52
dumb:

Боюсь, что всё-таки многие, использующие ProcessMessages, воспринимают его просто как заклинание, которое позволяет программе не виснуть, не понимая, что именно при этом происходит. Вообще, по поводу сообщений и их обработки просто легенды настоящие ходят, откуда только что берётся. Помню, один человек меня убеждал, что таймер работает в отдельной нити, и если обработка WM_Timer занимает слишком много времени, обработка следующего WM_Timer начнётся раньше, чем закончится предыдущего, грозился пример прислать. Когда прислал, то, естетсвенно, оказалось, что в обработчике WM_Timer вызывается ProcessMessages smile Так что вменяемость всех, кто использует ProcessMessages - это из области утопии smile

Автор: MetalFan 5.3.2008, 17:21
Цитата(GrigorievAnton @  5.3.2008,  15:52 Найти цитируемый пост)
 Так что вменяемость всех, кто использует ProcessMessages

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

Добавлено через 38 секунд
з.ы. ведь кто-то и goto в delphi до сих пор применяет, и считает себя вполне вменяемым...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)