powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как организовать ожидание пока Thread не отработает задание
25 сообщений из 78, страница 3 из 4
Как организовать ожидание пока Thread не отработает задание
    #39643578
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonЗакусывать надоКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643579
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockmakhaonЗакусывать надоКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Это, наверное, как экстремальное программирование, когда мысль прет
и хочется в туалет.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643586
stanilarА меня учили что в Дельфи для модульности используются Unit'ы.


Простой пример
Код: pascal
1.
Result  := UnitName.FunctionName();



В идеале он сам должен подхватит ближайшую объявленную функцию
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643643
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanЭто, наверное, как экстремальное программирование, когда мысль прет

А почему не: "А зачем это в дельфистам"?


YuRockКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Чуть постарше Дельфи. Наверное.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643646
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МиксионисюниПростой пример

Пример чего? Что для разделения нужны юниты?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643648
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockКстати, "реактивное программирование" - интересный термин. Новый наверно, раньше не встречал.
Чуть постарше Дельфи. НаверноеПогуглил. Да, есть такое.
Нет, не старше, но это не важно.
Важно то, что в "реактивном программировании" речь идет о потоках данных.
А в этом топике - о потоках кода.
Это, как бы, разные сущности.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643654
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockА в этом топике - о потоках кода.

Автору нужно получить событие о завершении работы расчетного потока. Как раз событие завершение работы расчетного потока и есть поток данных. По сути реактивность это те-же потоки.

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

Удобно именно с точки зрения оформления кода. Конечно, можно посмотреть есть ли что в OTL, но дельфя у меня уже давно не стоит.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643658
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilar,

Всё, что ты написал, делается элементарно и на делфи и на чем угодно. Тупо вызвать коллбэки (извини, "события") у подписанных "читателей".

Только это ад несусветный. Да, иногда - удобно. Как в экселе - одна ячейка другие обновляет. Но в общем - нет.

Автору нужно не это, не огород "событий" городить. Ему нужно просто организовать очередь и в других потоках дожидаться выполнения заданий, добавленных в эту очередь.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643662
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockделается элементарно ...
В сферическом примере - да. На практике будут разные ситуации типа преждевременного завершения ожидающего потока. Или ожидания разными потоками получения одинаковых данных.

YuRockогород
Вот как раз колхозить огород тут предлагаешь именно ты. Мое предложение (будь такая возможность) - воспользоваться проработанной теорией (а если говорить про другие ЯП то и практикой).
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643668
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockделается элементарно ...
В сферическом примере - да. На практике будут разные ситуации типа преждевременного завершения ожидающего потокаНу это если сделать "две функции", как предлагаешь ты. А если мониторить отписку читателей - проблемы такой не будет.
Все, конечно, больше и больше усложняется. Именно это наверно и нужно автору - усложнить задачу. Получается, так.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643669
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarВот как раз колхозить огород тут предлагаешь именно ты. Мое предложение (будь такая возможность) - воспользоваться проработанной теорией (а если говорить про другие ЯП то и практикой).Мой колхозный огород - прост, понятен и нагляден как 3 копейки.
В отличие от "теории".
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643672
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockМой колхозный огород - прост, понятен и нагляден как 3 копейки.

А еще он ничем не отличается от моего. В очередь ведь будут добавляться что-то типа колбэков(событий)?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643673
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockА если мониторить отписку читателей - проблемы такой не будет.

В реактивности, аналогично, можно отписаться от сервера событий. Речь то, на самом деле, про наличие проработанных компонент.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643675
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockМой колхозный огород - прост, понятен и нагляден как 3 копейки.

А еще он ничем не отличается от моего. В очередь ведь будут добавляться что-то типа колбэков(событий)?Нет, конечно. Просто указатель на память под результат (если нужно).
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643679
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockНет, конечно.
А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, проверять наличие данных?
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643751
stanilar,
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
program LiTh;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  PJob = ^TJob;
  TJob = class
    private
      fRef    :Integer;
      fCount  :Integer;
      fData   :Pointer;
      fResult :Pointer;
      eOk     :Pointer;
      eWait   :Pointer;
      eRef    :Pointer;
      class procedure Signal(aEvent: Pointer); static; inline;
      class procedure Wait(aEvent: Pointer); static; inline;
    public
      constructor Create;
      destructor  Destroy; override;
      function  IncRef:Integer;
      procedure DecRef;
      function  Send(aData :Pointer):Pointer;
      function  Next(var aData :Pointer; var aResult :PPointer):Boolean;
  end;

constructor TJob.Create;
begin
  eOk := System.MonitorSupport.NewWaitObject();
  eRef := System.MonitorSupport.NewWaitObject();
  eWait := System.MonitorSupport.NewWaitObject();
end;

destructor TJob.Destroy;
begin
  while True do begin
    Wait(eRef);
    if fRef = 1 then Send(nil)
      else if fRef = 0 then Break;
  end;
  System.MonitorSupport.FreeWaitObject(eWait);
  System.MonitorSupport.FreeWaitObject(eRef);
  System.MonitorSupport.FreeWaitObject(eOk);
  inherited;
end;

class procedure TJob.Wait(aEvent: Pointer);
begin
  System.MonitorSupport.WaitOrSignalObject(nil, aEvent, INFINITE);
end;

class procedure TJob.Signal(aEvent: Pointer);
begin
  System.MonitorSupport.WaitOrSignalObject(aEvent, nil, 0);
end;


function TJob.IncRef:Integer;
begin
 Result := AtomicIncrement(fRef);
end;

procedure TJob.DecRef;
begin
  AtomicDecrement(fRef);
  Signal(eRef);
end;

function TJob.Send(aData: Pointer): Pointer;
begin
  System.TMonitor.Enter(Self);        // становимся в очередь
  fData := aData;                     // данные задания
  Signal(eWait);                      // сигнал о задании
  if Assigned(aData) then begin
    Wait(eOk);                        // ожидание выполнения
    Result := fResult;                // забераем результат
WriteLn(IntToStr(NativeInt(Result))); // Debug
  end;
  System.TMonitor.Exit(Self);         // уходим из очереди
end;

function TJob.Next(var aData: Pointer; var aResult: PPointer):Boolean;
begin
  if fCount>0 then Signal(eOk);       // сигнал о выполнении
  Wait(eWait);                        // ожидание задания
  aData := fData;                     // какие данные
  aResult := @fResult;                // куда результат
  Result := Assigned(aData);
  Inc(fCount);
end;

function BeginThread(ThreadFunc: TThreadFunc; Parameter: Pointer): NativeInt;
{$IFDEF POSIX}
 var d : NativeUInt; begin Result := System.BeginThread(nil, ThreadFunc, Parameter, d); end;
{$ENDIF POSIX}
{$IFDEF MSWINDOWS}
 var d : Cardinal;  begin Result := System.BeginThread(nil, 0, ThreadFunc, Parameter, 0, d); end;
{$ENDIF MSWINDOWS}


procedure Thread1(Job:TJob);
var
 aData   : Pointer;
 aResult : PPointer;
begin
 Job.IncRef;
   while Job.Next(aData, aResult)     // данные поступили
     do aResult^ := PByte(aData)+1;   // работаем
 Job.DecRef;
end;

procedure Thread234(Job:TJob);
var
 i      : Integer;
 Data   : Pointer;
 Result : Pointer;
begin
 i := Job.IncRef * 100;
   for i := i to i+3 do begin
     Data := Pointer(i);
     Result := Job.Send(Data);        // делегируем
     Sleep(Random(100));
   end;
 Job.DecRef;
end;
                                      // // // // // // //
var
  i:Integer;
  Job : TJob;
begin
  Job := TJob.Create;
    BeginThread(@Thread1, Job);
    for i := 2 to 4 do BeginThread(@Thread234, Job);
  Job.Free;
  Writeln('Fin');
end.

...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643787
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stanilarYuRockНет, конечно.
А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, проверять наличие данных?Взвести событие, сигнализирующее об этом.
Не коллбэк, а событие, которого ожидающий поток ждет и спит при этом, без всяких циклов.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643849
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRockstanilarпропущено...

А как сообщить ждущему потоку, что данные пришли? Он будет сам, в цикле, ш8проверять наличие данных?Взвести событие, сигнализирующее об этом.
Не коллбэк, а событие, которого ожидающий поток ждет и спит при этом, без всяких циклов.

Вот сейчас как раз сижу, разбираюсь с TEvent
Штудирую конец этой статьи: Потоки и методы их синхронизаций в Delphi
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643853
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

Хватит TSimpleEvent. TEvent - именованные - для междупроцессных взаимодействий.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643950
stanilar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
истопник в кедах

Ну не цикл конечно, тем более что способ реализации WaitOrSignalObject выходит не только за рамки моей компетенции но и интересов(подразумевается, что реализация могла быть через цикл). Но смысл дискуссии был немного про другое. Вот ты, вместо того, чтоб передать коллбэк из потока в общий список, передал коллбэк реализации списка в поток. И что, теперь коллбэк перестал быть коллбэком?

P/S/ Не радует меня справка любимой среды

WaitOrSignalObject helpEmbarcadero Technologies does not currently have any additional information. Please help us document this topic by using the Discussion page!
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643980
stanilar
я это, адресатом ошибся. Пример ТС-у был - в ответ на его картинку. Ну и типа кроссплатформа.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
 //system.pas 
  PMonitorSupport = ^TMonitorSupport;
  TMonitorSupport = record
    // Obtain a synchronization object - usually an auto-reset event or semaphore
    NewSyncObject: function: Pointer;
    // Free the synchronization object obtained from NewSyncObject
    FreeSyncObject: procedure (SyncObject: Pointer);
    // Obtain a wait object - usually an auto-reset event or semaphore - these should be cached
    NewWaitObject: function: Pointer;
    // Return the wait object from NewWaitObject back to the cache
    FreeWaitObject: procedure (WaitObject: Pointer);
    // Wait for either a SyncObject or WaitObject or signal an object
    // o WaitOrSignalObject(nil, Obj, Timeout); - Wait for <Timeout> time or until <Obj> is signaled
    // o WaitOrSignalObject(Obj, nil, 0); - Signal <Obj> and return. Timeout and WaitObject params ignored.
    WaitOrSignalObject: function (SignalObject, WaitObject: Pointer; Timeout: Cardinal): Cardinal;
  end;


Если про коллбэк - то вопрос в том, в контексте какого потока он будет выполнен и как это реализовать.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643989
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я еще во многом не разобрался, но вот в процессе поиска попалась мне очень настораживающая статья: WaitForSingleObject. Why you should never use it. . Там как раз обыгрывается моя ситуация с COM объектами в потоке и как следствие скрытые окна и возможные блокировки. Но я еще не всё осознал.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643997
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Thread,

1. Статью не читал. Эта функция - основа всех основ.
2. Если твои COM-объекты окна любят выбрасывать - то, конечно, в доп. потоке реализовать работу будет сложно, мягко говоря.
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39643998
Threadнастораживающая статья: WaitForSingleObject. Why you should never use it. . а ещё https://www.transl-gunsmoker.ru/2010/03/msgwaitformultipleobjects.html и тогда
Код: pascal
1.
while true do 'Think carefully about whether a thread is the right solution to the problem';
...
Рейтинг: 0 / 0
Как организовать ожидание пока Thread не отработает задание
    #39644480
Thread
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем, кто откликнулся!

Я решил (как мне кажется) проблему через два TEvent'a. Ниже выкладываю код диаграмму работы.
Бросьте пожалуйста взгляд, всё ли в порядке.


TThread1 = class(TThread)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
type
   TThread1 = class(TThread)
   private
      FBusy                         : boolean;

      FRequest                      : string;
      FAnswer                       : string;

      FWaitRequestEvent             : TEvent;
      FOnRequestProcessedEvent      : TEvent;
   public
      procedure  AfterConstruction(); override;
      destructor Destroy(); override;
      procedure Execute(); override;

      procedure SyncExecute(const ARequest: string; var AAnswer: string);
   public
      property Busy: boolean read FBusy;
   end;


procedure TThread1.AfterConstruction();
begin
   inherited;

   FWaitRequestEvent:=TEvent.Create(nil, True, False, CreateGUID());

   FBusy := false;
end;


destructor TThread1.Destroy();
begin
   FWaitRequestEvent.Free();
   
   inherited;
end;


procedure TThread1.SyncExecute(const ARequest: string; var AAnswer: string);
var
   RequestProcessedEvent   : TEvent;
   WaitResult              : TWaitResult;
begin
   FRequest:=ARequest;
   FAnswer:='';

   FWaitRequestEvent.ResetEvent();

   RequestProcessedEvent := TEvent.Create(nil, True, False, CreateGUID());
   try
      FOnRequestProcessedEvent:=RequestProcessedEvent;
      FWaitRequestEvent.SetEvent();

      WaitResult := FOnRequestProcessedEvent.WaitFor(INFINITE);
   finally
      FOnRequestProcessedEvent := nil;
      FreeAndNil(RequestProcessedEvent);
   end;

   AAnswer:= FAnswer;
end;


procedure ___ProcessMessages();
var
   lpMsg    : TMsg;
begin
   while PeekMessage(lpMsg,0,0,0,PM_REMOVE) do
   begin
      TranslateMessage(lpMsg);
      DispatchMessage(lpMsg);
   end;
end;


procedure TThread1.Execute();
var
   ComObjects              : TMyComObjects;
   WaitResult              : TWaitResult;
begin
   CoInitialize(nil);
   try
      ComObjects := TMyComObjects.Create();
      try
         while not Terminated do
         begin
            WaitResult := FWaitRequestEvent.WaitFor(50); //50ms is not too long

            if WaitResult = wrSignaled then
            begin
               FBusy:=true;
               try
                  FWaitRequestEvent.ResetEvent();

                  Sleep(50); //50ms for preparing of FOnRequestProcessedEvent

                  try
                     ComObjects.XYZ(FRequest, FAnswer);
                  
			finally
                     FBusy:=false;
                  end;

                  if Assigned(FOnRequestProcessedEvent) then
                  begin
                     FOnRequestProcessedEvent.SetEvent();
                     FOnRequestProcessedEvent:=nil;
                  end;
               finally
                  FBusy:=false;
               end;
            end;
         end;
      finally
         if Assigned(FOnRequestProcessedEvent) then
         begin
            FOnRequestProcessedEvent.SetEvent();
            FOnRequestProcessedEvent:=nil;
         end;

         FreeAndNil(ComObjects);
         ___ProcessMessages(); // без этого вылетает Access Violation при уничтожении thread'a
      end;
   finally
      CoUnInitialize();
   end;
end;


...
Рейтинг: 0 / 0
25 сообщений из 78, страница 3 из 4
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как организовать ожидание пока Thread не отработает задание
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]