Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Synchronize


Страницы:   1 2 3

3APA3A ©   (2004-07-04 00:29:00) 

Что делает Synchronize? Я использую его и в общих чертах представляю что этот метод делает, но мне этого мало...


y-soft   (2004-07-05 11:37:00) [21]

>default ©   (05.07.04 11:10) [27]

Это уже варианты реализации. Приводя пример, я просто хотел показать, что во многих случаях совсем не обязательно синхронизировать, можно обойтись простым уведомлением.

Инструментальному потоку в приведенном примере совсем без разницы, когда и как поток GUI будет выполнять визуализацию, а важно лишь уведомить поток GUI, что данные обновились.

Аналогично и потоку GUI "по барабану", что конкретно делает инструментальный поток, ему важно лишь знать, что необходимо произвести перерисовку.

Необходимость в синхронизации возникает лишь при доступе к  совместно используемым данным (если таковые есть), но это дешевле сделать напрямую при помощи объектов синхронизации или функций InterlockedXXX

В общем случае потоки могут даже не знать о существовании друг друга (если для уведомления использовать события)...


default   (2004-07-05 11:36:00) [22]

jack128 ©   (05.07.04 11:34) [28]
на мой взгляд, только так и надо делать учитывая
"т.к. очень важны своевременное получение и обработка данных."
объясни тогда как будет работать Asynchronize(


jack128   (2004-07-05 11:34:00) [23]


> [27] default ©   (05.07.04 11:10)
А зачем такие сложности? Твой вариант будет напряжнее для системы, чем вариант y-soft'a. И вообще почему все так сильно против Asynchronize? вполне нормальная идея..


default   (2004-07-05 11:10:00) [24]

y-soft ©   (05.07.04 10:36) [26]
можно передавать эти данные от сервера потоку диспетчеру который будет вслучае отсутствия(вначале) или занятости потока(ов) обработки создавать другой поток обработки
вслучае если число своб-ых потов больше 1 убивать лишние
потоки будут выставлять флаг занятости в Execute, например
вот и достигли параллельной обработки...


y-soft   (2004-07-05 10:36:00) [25]

>panov ©   (05.07.04 10:26) [25]

Простой жизненный пример:

Есть GUI поток и инструментальный поток, который ведет интенсивный обмен с сервером. При получении данных этот инструментальный поток обрабатывает их, помещает результаты в какую-то структуру и уведомляет поток GUI. Поток GUI визуализирует измененные результаты (это, кстати, из-за большого количества контролируемых объектов процесс довольно длительный). Делать это синхронно и заставлять ждать инструментальный поток неприемлемо, т.к. очень важны своевременное получение и обработка данных.

И это еще очень простой случай


panov   (2004-07-05 10:26:00) [26]

y-soft ©   (05.07.04 10:22) [24]

Synchronize, конечно, полностью оправдывает свое название, но я о том, что в TThread очень не хватает метода Asynchronize :)

Ну это уже извращение бдет-)

От куда же заранее может быть известно, в каких условиях будет выполняться этот "Asynchronize" ;)

По отношению к какому потоку?


y-soft   (2004-07-05 10:22:00) [27]

>panov ©   (05.07.04 10:05) [23]

Саша, не хочу заниматься самоцитированием ([7],[11])

Synchronize, конечно, полностью оправдывает свое название, но я о том, что в TThread очень не хватает метода Asynchronize :)


panov   (2004-07-05 10:05:00) [28]

>y-soft ©   (05.07.04 09:33) [22]

Так Synchronize для того и придумана была, чтобы выполнение процедуры происходило в основном потоке-)

Естественно, в это время дополнительный поток должен ожидать завершения выполнения целиком процедуры, которая указана в Synchronize. Т.е. процедура не может быть выполнена частичнов потокобезопасном режиме.-)


y-soft   (2004-07-05 09:33:00) [29]

>default ©   (05.07.04 09:28) [20]

Долго же Borland собирался, но все равно упорно останавливает поток-источник на время выполнения Synchronize :)


Romkin   (2004-07-05 09:29:00) [30]

Не путайтесь. Начиная с D6 syncronize работает через критическую секцию, до этого - через SendMessage. И в том, и в другом случае вызывающий поток ждет окончания обработки


default   (2004-07-05 09:28:00) [31]

y-soft ©   (05.07.04 09:09) [19]
понятно, я хотел написать что можно сделать и через SendMessage
просто вслучае с PostMessage-ом вызывающий поток засыпает по своему event-у в Synchronize после PostMessage в ожидании флага обработки, а в случае SendMessage подобные действия делает за нас ОС


y-soft   (2004-07-05 09:09:00) [32]

>default ©   (05.07.04 09:00) [17]

всё же через PostMessage

А вот так реализовано в Delphi 5:

procedure TThread.Synchronize(Method: TThreadMethod);
begin
 FSynchronizeException := nil;
 FMethod := Method;
 SendMessage(ThreadWindow, CM_EXECPROC, 0, Longint(Self));
 if Assigned(FSynchronizeException) then raise FSynchronizeException;
end;


y-soft   (2004-07-05 09:05:00) [33]

>KSergey ©   (05.07.04 08:45) [14]

Придется цитировать:

...если поток посылает сообщение окну, созданному другим потоком, операции, выполняемые функцией SendMessage, значительно усложняются...
[Вырезано]
...чтобы один поток мог отправить сообщение окну, созданному другим потоком, система должна выполнить следующие действия.
   Во-первых, переданное сообщение присоединяется к очереди сообщений потока-приемника, в результате чего для этого потока устанавливается флаг QS_SENDMESSAGE. Во-вторых, если поток-приемник в данный момент выполняет какой-то код и не ожидает сообщений (через вызов GetMessage, PeekMessage или WaitMessage), переданное сообщение обработать не удастся - система не прервет работу потока для немедленной обработки сообщения. Но когда поток-приемник ждет сообщений, система сначала проверяет, установлен ли флаг пробуждения QS_SENDMESSAGE, и, если да, просматривает очередь синхронных сообщений, отыскивая первое из них. В очереди может находиться более одного сообщения. Скажем, несколько потоков одновременно послали сообщение одному и тому же окну. Тогда система просто ставит эти сообщения в очередь синхронных сообщений потока...


default   (2004-07-05 09:00:00) [34]

Григорьев Антон ©   (04.07.04 07:02) [6]
всё же через PostMessage
"procedure TThread.Synchronize(Method: TThreadMethod);
var
 SyncProc: TSyncProc;
begin
{$IFDEF MSWINDOWS}
 SyncProc.Signal := CreateEvent(nil, True, False, nil);
 try
{$ENDIF}
{$IFDEF LINUX}
   FillChar(SyncProc, SizeOf(SyncProc), 0);  // This also initializes the cond_var
{$ENDIF}
   EnterCriticalSection(ThreadLock);
   try
     FSynchronizeException := nil;
     FMethod := Method;
     SyncProc.Thread := Self;
     SyncList.Add(@SyncProc);
     ProcPosted := True;
     if Assigned(WakeMainThread) then
        WakeMainThread(Self);
{$IFDEF MSWINDOWS}
     LeaveCriticalSection(ThreadLock);
     try
       WaitForSingleObject(SyncProc.Signal, INFINITE);
     finally
       EnterCriticalSection(ThreadLock);
     end;
{$ENDIF}
{$IFDEF LINUX}
     pthread_cond_wait(SyncProc.Signal, ThreadLock);
{$ENDIF}
   finally
     LeaveCriticalSection(ThreadLock);
   end;
{$IFDEF MSWINDOWS}
 finally
   CloseHandle(SyncProc.Signal);
 end;
{$ENDIF}
 if Assigned(FSynchronizeException) then raise FSynchronizeException;
end;"
procedure TApplication.WakeMainThread(Sender: TObject);
begin
  PostMessage(Handle, WM_NULL, 0, 0);
end;"


KSergey   (2004-07-05 08:52:00) [35]

> [15] default ©   (05.07.04 08:50)

Ну если так все уже классно придумано за нас... признаться не знал. Спасибо.


default   (2004-07-05 08:50:00) [36]

KSergey ©   (05.07.04 08:45) [14]
очередь есть, она, естественно, приоритетней чем очередь PostMessage
нафиг нужна?
процедура окна вызывается только в том потоке который создал окно соотв-ее данной  процедуре(чтобы не приходилось писать потокобезапасные процедуры окна)
а что будет если произв-ти вызов SendMessage в разных потоках при таких условиях?необходима очередь...


KSergey   (2004-07-05 08:45:00) [37]

> [11] y-soft ©   (04.07.04 21:26)

Ммм... Правда никто не возражает, может я правда что не понимаю, но всегда считал что ни о какой очереди сообщений для SendMеssage просто не существует.
Из ее тела вызывается оконная процедура (именно непосредственно выызывается) - и все. Вернулись из оконной процедуры - вернулись и из SendMessage. И в контексте того потока, который вызвал SendMessage.

Так о какой очереди сообщений идет речь в контексте SendMessage??


y-soft   (2004-07-05 07:51:00) [38]

>Fay   (05.07.04 03:44) [12]

Джеффри Рихтер "Windows. Создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows", "Питер", 2001, ISBN 5-272-00384-5


Fay   (2004-07-05 03:44:00) [39]

2y-soft ©   (04.07.04 21:26) [11]

> 2. Дж. Рихтер Глава 26

Глава чего?


y-soft   (2004-07-04 21:26:00) [40]

>Rouse_ ©   (04.07.04 14:36) [10]

Ну что ж, придется подробнее разъяснить, что я имел в виду

Сообщения, посланные PostMessage и SendMessage, помещаются в разные очереди, причем очередь синхронных сообщений имеет больший приоритет. Говоря о торможении, я имел в виду именно задержку обработки в очереди синхронныхсообщений.  

Что касается PostMessage, то она (в отличие от SendMessage) возвращает управление сразу, как только сообщение будет поставлено в очередь вызываемого потока. И в этом случае вызывающий поток фактически не тормозится.

Теперь о том, так ли уж всегданеобходимо  ждать завершения обработки посланного сообщения?

Как показывает опыт - чаще всего нет. В большинстве случаев Syncronize используется только для того, чтобы просто вызвать в основном потоке какие-то функции GUI (спасибо, Borland, за потоконебезопасность VCL!). От того, что перерисовка будет произведена не мгновенно, а через некоторый (небольшой) промежуток времени, ничего страшного не произойдет, зато не будет "скачков" и "замираний" курсора, отставания отображения ввода с клавиатуры и пропадания "тиков" таймеров.

Понятно, что я не имел в виду случаи, когда действительно необходимо ждать гарантированного завершения обработки события (хотя, честно говоря, для Win32 более естественным в этом случае является использование событий и Wait-функций или APC)

При большом желании можно, конечно, и с помощью слишком частого вызова PostMessage забить очередь асинхронных сообщений, но это уже из другой области :)

P.S. На всякий случай указываю авторитетные источники информации об особенностях работы очередей сообщений:

1. MSDN
2. Дж. Рихтер Глава 26

P.P.S. Ничего личного :)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо