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

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

Синхронизация через SendMessage [D2005, XP]


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

Alex4445 ©   (2015-12-15 22:37:00) 


type
TMyForm = class (TForm)
...
  procedure SyncMsg (var T : TMessage); message WM_USER + 1;
end

var
  MyForm : TMyForm;

procedure TMyForm.SyncMsg (var T : TMessage);
begin
  CSL.Send ('Enter');   // CodeSiteLogger   - система логгирования
  sleep (2000);
  CSL.Send ('Leave');
end;



TMyThread = class (TThread)
 procedure Execute; override;
end;

procedure TMyThread.Execute;
begin
    while (not Terminated) do
        SendMessage (MyForm.Handle,WM_USER+1,0,0);
        sleep (100);
    end;
end;



Создается несколько однотипных потоков, которые через SendMessage выполняют определенный код (в данному случае лог + слип) в главном потоке.

Ожидаю увидеть в логе:

Enter
Leave
Enter
Leave
...
Enter
Leave
...

Т.е главный поток обрабатывает SendMessage-ы последовательно.

Вижу

Enter
Leave
Enter   // ???
Enter   // ???
Leave
Enter
Leave
...

Как такое получается?  Как начал выполняться последующий SendMesssage пока не завершился предыдущий?
Или это "обман" связанный с работой логгера ?


Alex4445   (2015-12-16 13:02:00) [41]



procedure TMyThread.Execute;
begin
   while (not Terminated) do
        FCS.Enter;   // TCriticalSection
          SendMessage (MyForm.Handle,WM_USER+1,0,0);
        FCS.Leave;
        sleep (100);
   end;
end;


Вот такой код должен быть?
Разве сам SendMessage  - не гарантирует синхронизации ???


Rouse_   (2015-12-16 12:10:00) [42]

А стоп, да затупил - Коля прав, не прочитал про множественные вызовы.
Да, вызов из второй нити приостановит выполнение кода из первой, поэтому в данном случае критсекция нужна


Alex4445   (2015-12-16 12:02:00) [43]


> вряд ли. SendMessage немедленное выполнение, без очереди,
>  код процедуры не заблокирован, критической секции нет.
> ничего не мешает второму потоку вызвать свой SendMessage
> в момент когда первый на sleep-е. sleep в принципе и нужен
> чтобы "притушить" выполнение текущего, и дать "подышать"
> другим потокам. вот они и пользуются. это же фактически
> прямой вызов кода, все одно, что функцию описанную прямо
> в потоке (или неважно
> имхо, для логера нужен отдельный поток

где) вызвать.
> поменяй на PostMessage, очередь событий должна исправить
> ситуацию.


Хмм.. как это "без очереди"?  
И Send и Post через очередь сообщений, отличие Send.. от Post.. что первый ждет завершения, а второй - нет.


> а посчитай количество Enter-ов и Leave. первых случаем не
> больше?

Нет. Все как нужно.


sniknik   (2015-12-16 01:45:00) [44]

> синхронизация на первый взгляд валидная
вряд ли. SendMessage немедленное выполнение, без очереди, код процедуры не заблокирован, критической секции нет. ничего не мешает второму потоку вызвать свой SendMessage в момент когда первый на sleep-е. sleep в принципе и нужен чтобы "притушить" выполнение текущего, и дать "подышать" другим потокам. вот они и пользуются. это же фактически прямой вызов кода, все одно, что функцию описанную прямо в потоке (или неважно где) вызвать.
поменяй на PostMessage, очередь событий должна исправить ситуацию.
или
+, еще вариант
> Как такое получается?
а посчитай количество Enter-ов и Leave. первых случаем не больше? в смысле может быть приходит "паразитное", забытое сообщение из другого места с тем же кодом?

имхо, для логера нужен отдельный поток + PostThreadMessage, а не основной c событием на форму.


Rouse_   (2015-12-16 00:03:00) [45]

Скорее логер, синхронизация на первый взгляд валидная


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

Наверх

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