powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как правильно заморозить поток из самого себя?
74 сообщений из 74, показаны все 3 страниц
Как правильно заморозить поток из самого себя?
    #40050066
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Программа рассылки сообщений корпоративным пользователям компании должна рассылать сообщения только в определенное время, например, с 8 утра до 18 часов вечера.
Так вот, такой код просто загружает проц на 15%
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
procedure TSendNotifyThread.Execute;
begin
...
...

// fTimeStartNotyfy - время начал рассылок
// fTimeStopNotyfy - время окончания рассылок
// System.SysUtils.Time - текущее время
// fSendNotifyInerval - интервал рассылки, каждые 5 сек.


  while not Terminated do
  begin
    try
      if Terminated then Break;

      // рассылка разрешена только в указанное время
      if (System.SysUtils.Time <= fTimeStartNotyfy) or (System.SysUtils.Time >= fTimeStopNotyfy) then
        Continue;// пропускаем цикл если время не подходящее

      if WaitForSingleObject(FTerminateEvent, fSendNotifyInerval) <> WAIT_ABANDONED then 
      begin
// рассылка сообщений



т.е. вместо Continue нужно поставить
Код: pascal
1.
WaitForSingleObject(FTerminateEvent, XXX);


XXX - это количество миллисекунд до 8 утра, когда настанет резрешенное время.

или я все равно неправильно сделаю?

Подскажите, как правильно усыпить поток и запустить из самого себя, так сказать?
Ну и переписывать это всё не хочется.

Спасибо.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050070
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
т.е. вместо Continue нужно поставить
Код: pascal
1.
WaitForSingleObject(FTerminateEvent, XXX);



XXX - это количество миллисекунд до 8 утра, когда настанет резрешенное время.
Это один из вариантов. Второй использовать WaitableTimer и ждать двух событий: либо таймер, либо сообщения на завершение программы
X11
Код: pascal
1.
 if WaitForSingleObject(FTerminateEvent, fSendNotifyInerval) <> WAIT_ABANDONED then 

Почитай что такое WAIT_ABANDONED. Это точно не то, что тебе нужно
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050073
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Почитай что такое WAIT_ABANDONED. Это точно не то, что тебе нужно


неа, пока не понял..
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050075
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
использовать WaitableTimer

это оно?

https://gist.github.com/perevoznyk/1f554a2bd4b7523701c6d9e26dc7a473
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050077
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
неа, пока не понял..
Это отказ соседнего процесса от мьютекса
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050079
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
это оно?
Функции те, но код страшный. MsgWaitForMultipleObjects не нужен точно. Достаточно будет WaitForMultipleObjects. И liDueTime.QuadPart тебе удобнее будет использовать положительный. Так сразу можно установить время срабатывания
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050084
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
X11
это оно?
Функции те, но код страшный. MsgWaitForMultipleObjects не нужен точно. Достаточно будет WaitForMultipleObjects. И liDueTime.QuadPart тебе удобнее будет использовать положительный. Так сразу можно установить время срабатывания

В общем-то для этой задачи достаточно одного обычного эвента (который уже есть). Ждать по 60 секунд, после ожидания - проверять Terminated, если не выход - проверять насписание, если пора - отправлять почту, нет - Continue.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050085
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
_Vasilisk_
Почитай что такое WAIT_ABANDONED. Это точно не то, что тебе нужно


неа, пока не понял..
Если на что-то и проверять - то разве что на WAIT_FAILED, для логирования логических ошибок разработки.
А так - не важно, что он вернет - таймаут или сработку - на Terminated проверять всё равно надо и лучше.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050087
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11,

а чем тебя не устраивают паузы в стиле:
Код: pascal
1.
2.
    ServiceThread.ProcessRequests(False);
    Sleep(10);

Проц не грузит, служба не зависает...
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050091
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sleep(1000) перед Continue да и все.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050093
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Проц не грузит

Ещё как грузит, просто ты за своими гигагерцами это не замечаешь. Посмотри в
ProcessExplorer счётчики переключения контекстов.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050100
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

asutp2Проц не грузит

Ещё как грузит, просто ты за своими гигагерцами это не замечаешь. Посмотри в
ProcessExplorer счётчики переключения контекстов.
Когда диспетчер задач непрерывно показывает ЦП 0% у сервиса с подобной реализацией простоя, действительно сложно заметить :-)
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050131
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
_Vasilisk_
использовать WaitableTimer

это оно?

https://gist.github.com/perevoznyk/1f554a2bd4b7523701c6d9e26dc7a473


такс... а тут используется Application.ProcessMessages;
а для потоков это норм?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050133
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
И liDueTime.QuadPart тебе удобнее будет использовать положительный. Так сразу можно установить время срабатывания


Т.е. просто минус убрать?
или еще что-то менять надо?


И что значит "Так сразу можно установить время срабатывания"?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050134
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11


такс... а тут используется Application.ProcessMessages;
а для потоков это норм?

это почти везде не норм, а для потоков это мрак и дичь.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050136
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. ту функцию уже точно нельзя использовать.

другие советы тоже под вопросом?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050146
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050152
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А виндовый планировщик не хочешь использовать?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050157
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мне бы что-то попроще

потому что наворотить такой код, в котором я долго не смогу разобраться и понять, что там к чему, не очень хотелось бы
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050164
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно так:
Код: 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.
procedure TSendNotifyThread.Execute;
begin
...

// fTimeStartNotyfy - время начал рассылок
// fTimeStopNotyfy - время окончания рассылок
// System.SysUtils.Time - текущее время
// fSendNotifyInerval - интервал рассылки, каждые 5 сек.


  while not Terminated do
  begin
    try
      if Terminated then Break;

      // рассылка разрешена только в указанное время
      case WaitForSingleObject(FTerminateEvent, fSendNotifyInerval) of // fSendNotifyInerval = 5000 мсек
        WAIT_OBJECT_0: break;
        WAIT_TIMEOUT: if (System.SysUtils.Time > fTimeStartNotyfy) and (System.SysUtils.Time < fTimeStopNotyfy)
          then
    // рассылка сообщений
        WAIT_FAILED: //обработка ошибки
     end;
...
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050165
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
_Vasilisk_
использовать WaitableTimer

это оно?

https://gist.github.com/perevoznyk/1f554a2bd4b7523701c6d9e26dc7a473


когда задействовал эту функцию Wait()

то madExcept по завершеню работы программы выдал просто ТУЧУ resource leaks
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050171
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11

Так вот, такой код просто загружает проц на 15%
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  while not Terminated do
  begin
    try
      if Terminated then Break;

      // рассылка разрешена только в указанное время
      if (System.SysUtils.Time <= fTimeStartNotyfy) or (System.SysUtils.Time >= fTimeStopNotyfy) then
        Continue;// пропускаем цикл если время не подходящее

// рассылка сообщений



Такой код грузит свое ядро на 100%.
А то что винда показывает около 15 - так это потому что проц многоядерный.
15% примерно соответствует Intel Core i7.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050184
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ProcessExplorer

Код: pascal
1.
2.
3.
4.
5.
      if (System.SysUtils.Time <= fTimeStartNotyfy) or (System.SysUtils.Time >= fTimeStopNotyfy) then
      begin
        Sleep(1000);
        Continue;// пропускаем цикл если время не подходящее
      end;
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050186
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ох...

Не грузит процессор, ожидает сообщения, минимум памяти, без обратной связи (но сделать просто).
Можно сделать массив с 1000 потоками и раскидывать между ними сообщения.
Расписание нужно организовывать в основном потоке, а эти - только для работы/отправки.

Код: 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.
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

type
  PThreadRecord = ^TThreadRecord;
  TThreadRecord = record
  private
    FHandle: THandle;
    FID: Cardinal;
    FNextMessage: Pointer;
    FEvent: THandle;
    FStopping: boolean;
  public
    function Start: boolean;
    function Enqueue(const AMessage: Pointer): boolean;
    function IsRinnung: boolean;
    function Stop: boolean;
  end;

{ TThreadRecord }

function ThreadMainLoop(Instance: Pointer): Integer;
begin
  result := 0;
  with PThreadRecord(Instance)^ do begin
    while not FStopping do begin
      if (WaitForSingleObject(FEvent, INFINITE) = 0) and (not FStopping) then begin
        ResetEvent(FEvent);
        if Integer(FNextMessage) <> -1 then begin
          Sleep(100); // working
        end;
        Integer(FNextMessage) := -1;
      end;
    end;
    CloseHandle(FEvent);
    FEvent := 0;
    CloseHandle(FHandle);
    FHandle := 0;
  end;
end;

function TThreadRecord.Enqueue(const AMessage: Pointer): boolean;
begin
  result := false;
  if LongBool(FHandle) and (not IsRinnung) then begin
    result := InterlockedCompareExchange(Integer(FNextMessage), Integer(AMessage), -1) = -1;
    if result then
      result := SetEvent(FEvent);
  end;
end;

function TThreadRecord.IsRinnung: boolean;
begin
  result := (FHandle > 0) and (not FStopping) and (Integer(FNextMessage) <> -1);
end;

function TThreadRecord.Start: boolean;
begin
  FHandle := 0;
  result := false;
  FEvent := CreateEvent(nil, true, false, '');
  if not LongBool(FEvent) then exit;
  Integer(FNextMessage) := -1;
  FStopping := false;
  FHandle := BeginThread(nil, 2*1024*1024, @ThreadMainLoop, @Self, $10000, FID);
  result := Fhandle > 0;
  if not result then begin
    CloseHandle(FEvent);
    FEvent := 0;
  end;
end;

function TThreadRecord.Stop: boolean;
begin
  FStopping := true;
  SetEvent(FEvent);
  result := true;
end;

var
  thread: TThreadRecord;
  p: integer;
  //m: Pointer;

begin
  ReportMemoryLeaksOnShutdown := true;
  //GetMem(m, 1024); // test for leaks
  try
    if thread.Start then begin
      Writeln('Started');
      p := $10;
      if thread.Enqueue(Pointer(p)) then Writeln('Enqueued ', IntToHex(p, 4));
      p := $12;
      if thread.Enqueue(Pointer(p)) then Writeln('Enqueued ', IntToHex(p, 4));
      p := $20;
      if thread.Enqueue(Pointer(p)) then Writeln('Enqueued ', IntToHex(p, 4));
      sleep(1000);
      p := $30;
      if thread.Enqueue(Pointer(p)) then Writeln('Enqueued ', IntToHex(p, 4));
      sleep(1000);
      if thread.Stop then writeln('Stoped');
    end;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
  readln;
end.

...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050189
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне не надо раскидывать между потоками сообщения (пока что).
Нужно (пока что) приостановить поток, а потом продолжить его работу.
Из самого себя.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050191
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11,

тебе дали 100% работающий код, а ты булькаешь не посмотрев его?
Или тут сложные конструкции?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050214
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Sleep(1000) перед Continue да и все.
Смысла нет, если можно заменить на Wait(1000) и не ждать секунду при закрытии.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050249
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
такс... а тут используется Application.ProcessMessages;
а для потоков это норм?
Конечно нет. Application.ProcessMessages и Sleep() имеет смысл вызывать только для отладки тестовых приложений. Больше никогда
X11
Т.е. просто минус убрать?
или еще что-то менять надо?
И что значит "Так сразу можно установить время срабатывания"?
Ну открой уже документацию
X11
когда задействовал эту функцию Wait()
то madExcept по завершеню работы программы выдал просто ТУЧУ resource leaks
Явных утечек в коде нет. Конечно если ты не вставил Application.ProcessMessages
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050261
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Смысла нет, если можно заменить на Wait(1000) и не ждать секунду при закрытии.


я написал, что после Wait madExcept выдает кучу leaks
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050285
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
я написал, что после Wait madExcept выдает кучу leaks


я так понял, что если завершить работу приложения во время Wait(), то не выполняется деструктор потока и куча объектов тоже не удаляется поэтому.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050290
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

Секунду перед закрытием можно и подождать.
Ничего страшного.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050295
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подождать до утра? Цель Wait() ждать до назначенного времени, например, до 8ми утра.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050304
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получается, что внутрь Wait нужно куда-то втиснуть корректно деструктор Destroy?

Когда я закрываю программу, то вот эта бряка не выполняется.
Я имею ввиду, что при закрытии программы, всё что после Wait не выполняется.

Т.е. нужно как-то заставить поток завершаться корректно, с выполнением деструктора.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050305
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
тебе дали 100% работающий код, а ты булькаешь не посмотрев его?
Или тут сложные конструкции?


Извини, к своему сожалению я там не нашел чего-то легко исправит мою проблему.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050311
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11,
а чем тебя не устроил предложенный мной вариант? Чуть измененный твой код. 22288865 Тикает раз в 5 сек, вне диапазона времени рассылки снова ждет, во время рассылки делает действие и после этого ждет. Чтобы не ожидая, закончить работу, "взводишь" событие из основного потока. Да, вариант не универсальный, а для конкретного случая, при других временных константах может быть будет не очень хорош, но при этих условиях решает задачу.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050316
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
YuRock
Смысла нет, если можно заменить на Wait(1000) и не ждать секунду при закрытии.


я написал, что после Wait madExcept выдает кучу leaks

Я не знаю, что такое madExcept. Так или иначе, утечки ресурсов происходят в одном единственном случае: если забывать их освобождать.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050320
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
X11
я написал, что после Wait madExcept выдает кучу leaks


я так понял, что если завершить работу приложения во время Wait(), то не выполняется деструктор потока и куча объектов тоже не удаляется поэтому.

завершить работу приложения во время Wait невозможно. Разве что TerminateProcess или ExitProcess.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050321
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
YuRock,

Секунду перед закрытием можно и подождать.
Ничего страшного.
Не вижу смысла. Даже строчек кода столько же. Меня лично раздражают эти лишние секунды. Секунда там, секунда здесь...
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050322
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
завершить работу приложения во время Wait невозможно. Разве что TerminateProcess или ExitProcess.
И зачем ты тогда предлагаешь wait?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050324
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatИ зачем ты тогда предлагаешь wait?

В надежде, что топикстартер не полный идиот и догадается ждать не просто время, а сигнал
"завершись". Хотя мог бы уже понять...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050326
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
YuRock
завершить работу приложения во время Wait невозможно. Разве что TerminateProcess или ExitProcess.
И зачем ты тогда предлагаешь wait?
Затем, что при использовании Wait (в отличие от Sleep) перед завершением приложения можно выйти из Wait.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050327
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

я пытаюсь
понять
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050333
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
льзовании Wait (в отличие от Sleep) перед завершением приложения можно выйти из Wait.


т.е.
Until (lBusy = WAIT_OBJECT_0) or (lBusy <> ???);

т.е. что правильно подставить вместо ???
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050338
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
YuRock
льзовании Wait (в отличие от Sleep) перед завершением приложения можно выйти из Wait.


т.е.
Until (lBusy = WAIT_OBJECT_0) or (lBusy <> ???);

т.е. что правильно подставить вместо ???

Ничего не подставить. Просто Wait и всё.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure TMyThread.Execute;
begin
  while not Terminalted do begin
    if ВремяПришло then
      Отправка почты;

    Wait(60000);
  end;
end;


А в деструкторе потока:
Код: pascal
1.
2.
3.
4.
5.
6.
procedure TMyThread.Destroy;
begin
  Terminate;
  SetEvent;
  inherited Destroy;
end;
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050339
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то я вообще запутался.
Как я ранее писал, Destroy не выполняется.

и зачем там Terminate и SetEvent?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050341
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Как я ранее писал, Destroy не выполняется.
Значит, его никто не вызывает. А зря.

X11
и зачем там Terminate и SetEvent?

Terminate - чтобы свойство Terminated стало =True.
SetEvent - чтобы прервался Wait.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050348
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И чтобы потом вся это кривобайда упала на обращении к освобождённому объекту. Великолепно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050349
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
создание
Код: pascal
1.
2.
3.
4.
5.
6.
SendNotifyThread := TSendNotifyThread.Create(True, DM.UniConnection1.ConnectString);
SendNotifyThread.FreeOnTerminate   := True;
...
...
...
SendNotifyThread.Start;




деструктор вызывается, если выполнить SendNotifyThread.Terminate;

вот код при закрытии приложения:
Код: pascal
1.
2.
3.
4.
5.
6.
    if Assigned(SendNotifyThread) then
    begin
      SendNotifyThread.Terminate;
      SetEvent(SendNotifyThread.EventHandle);
      SendNotifyThread := nil;
    end;



а вот если нужно принудительно остановить работу потока:
Код: pascal
1.
2.
3.
4.
SendNotifyThread.StopSendNotify := true;
SendNotifyThread.Terminate;
SetEvent(SendNotifyThread.EventHandle);
SendNotifyThread := nil;
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050350
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
И чтобы потом вся это кривобайда упала на обращении к освобождённому объекту. Великолепно.
Освобождение объекта (или хэндла) эвента - после inherited Destroy (после этого Execute уже гарантированно завершен). Я это не писал даже, как и создание.
Или ты о чем?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050353
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Код: pascal
1.
SendNotifyThread.FreeOnTerminate   := True;


1. У тебя в потоке вечный цикл. Какой нахрен FreeOnTerminate??? Убери это. Как и CreateSuspended=True - только лишняя строка Start из-за этого (ее тоже выкинь). Все создавай в конструкторе потока.

2. Весь свой код при завершении приложения выкинь, замени его на одну строку - SendNotifyThread.Free
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050355
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, но ничего я выкидывать не буду, пока всё работает нормально
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050356
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
а вот если нужно принудительно остановить работу потока:
Код: pascal
1.
2.
3.
4.
SendNotifyThread.StopSendNotify := true;
SendNotifyThread.Terminate;
SetEvent(SendNotifyThread.EventHandle);
SendNotifyThread := nil;


Замени это на FreeAndNil( SendNotifyThread );
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050357
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Спасибо, но ничего я выкидывать не буду, пока всё работает нормально

Зачем нам вопросы задавать, если лучше нас знаешь, как лучше.
П.С. Работает хоть как-то - очень случайно, это не нормально.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050359
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Замени это на FreeAndNil( SendNotifyThread );


Ты ведь даже не знаешь, что делает StopSendNotify(), а требуешь это убрать
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050363
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
YuRock
Замени это на FreeAndNil( SendNotifyThread );


Ты ведь даже не знаешь, что делает StopSendNotify(), а требуешь это убрать

Конечно же я знаю, что это такое. Протёр свой шар с утра.
Если эта переменная не полностью бесполезна и не только дублирует Terminated, то перенеси ее в деструктор (возле Terminate;), да и всё.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050372
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockОсвобождение объекта (или хэндла) эвента - после inherited Destroy (после этого Execute
уже гарантированно завершен).

Да ну? Это ты гарантируешь вызовом Terminate и SetEvent в деструкторе ?.. Ню-ню...


Раздел Рустама всегда полон людей, стреляющих себе в ногу, выходящих в окно и делающих
прочие самоубийственные глупости в стиле мистера Бина.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050374
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
YuRockОсвобождение объекта (или хэндла) эвента - после inherited Destroy (после этого Execute
уже гарантированно завершен).

Да ну? Это ты гарантируешь вызовом Terminate и SetEvent в деструкторе ?.. Ню-ню...


Раздел Рустама всегда полон людей, стреляющих себе в ногу, выходящих в окно и делающих
прочие самоубийственные глупости в стиле мистера Бина.
Без всяких ну.
Я это гарантирую вызовом inherited Destroy, в котором вызывается WaitFor.
Dimitry Sibiryakov
Раздел Рустама всегда полон людей, стреляющих себе в ногу, выходящих в окно

И любителей пукнуть в лужу.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050377
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эмм, из простейшей задачи раздули в непойми что)))
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050379
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
Эмм, из простейшей задачи раздули в непойми что)))
Задачи, как оказалось, не было. У ТС всё прекрасно работает.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050380
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2
Эмм, из простейшей задачи раздули в непойми что)))


я в шоке просто

ну да ,я пока решил вопрос с помощью
Код: pascal
1.
2.
Sleep(1000);
Continue;



хоть это и некорректно может быть, но проц не грузит
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050381
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
asutp2
Эмм, из простейшей задачи раздули в непойми что)))


я в шоке просто

ну да ,я пока решил вопрос с помощью
Код: pascal
1.
2.
Sleep(1000);
Continue;




хоть это и некорректно может быть, но проц не грузит
Жаль.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050421
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Это ты гарантируешь вызовом Terminate и SetEvent в деструкторе ?..
А в чем проблема?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050424
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_А в чем проблема?

FreeOnTerminate. Деструктор вызывается уже после того, как Execute завершилось.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050463
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
FreeOnTerminate. Деструктор вызывается уже после того, как Execute завершилось.
Допустим. Но ничего фатального кроме лишних телодвижений не происходит.

Главное, чтобы Event не закрыли по выходу из Execute
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050497
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
asutp2
Эмм, из простейшей задачи раздули в непойми что)))


я в шоке просто

ну да ,я пока решил вопрос с помощью
Код: pascal
1.
2.
Sleep(1000);
Continue;



хоть это и некорректно может быть, но проц не грузит


Рекомендую все-таки почитать статью по многопоточному программированию. Сколько ещё лет можно не разбираться с этой темой?
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050501
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
кроме лишних телодвижений
Каких лишних? Terminate лишний, потому что он есть в Destroy? Так он нужен обязательно до SetEvent.
Так-то я давно наследника написал с созданием в конструкторе этого эвента и этими тремя (четырьмя, с освобождением эвента после inherited) строчками в деструкторе. И использую его если не всегда, то почти всегда.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050502
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читал только часть последней страницы - если извне объект потока "трогают", то никаких FreeOnTerminate.
PS: если есть хоть малейшее недопонимание TThread
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050548
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev,

ну вроде бы нету, даже syncronize не использую за ненадобностью.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050652
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Каких лишних? Terminate лишний, потому что он есть в Destroy? Так он нужен обязательно до SetEvent.
Если FreeOnTerminate = True, то поток уже остановлен. Поэтому именно в этом случае остановка в деструкторе лишняя
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050695
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
YuRock
Каких лишних? Terminate лишний, потому что он есть в Destroy? Так он нужен обязательно до SetEvent.
Если FreeOnTerminate = True, то поток уже остановлен...
С чего ты так решил? Это флаг, который регулирует поведение при остановке потока. Его можно устанавливать хоть в конструкторе при запуске потока, а остановиться поток может и через месяц, и всё это время FreeOnTerminate = True...
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050704
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2Это флаг, который регулирует поведение при остановке потока.

Прааавильно. А тепепь попробуй подумать когда и откуда будет вызываться деструктор потока
если этот флаг установлен.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050731
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

а что думать? смотрим функцию ThreadProc в System.Classes.pas, там всё очевидно:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
  try
    Thread.FStarted := True;
    if not Thread.Terminated then
    try
      Thread.Execute;
    except
      Thread.FFatalException := AcquireExceptionObject;
    end;
  finally
    Result := Thread.FReturnValue;
    FreeThread := Thread.FFreeOnTerminate;
    Thread.DoTerminate;
    Thread.FFinished := True;
    SignalSyncEvent;
    if FreeThread then
    begin
      Thread.DisposeOf;


Соответственно FreeOnTerminate проверяется после завершения работы Thread.Execute, со всеми вытекающими.
Другой вопрос, что если у потока флаг FreeOnTerminate установлен, то хранить ссылку на него и обращаться по ней чревато экспешенами, т.к. поток может завершится в произвольный момент и сохраненные ссылки на него станут невалидными.
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050736
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О чём, собственно, тут и говорилось всю последнюю страницу.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как правильно заморозить поток из самого себя?
    #40050748
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
YuRock
Каких лишних? Terminate лишний, потому что он есть в Destroy? Так он нужен обязательно до SetEvent.
Если FreeOnTerminate = True, то поток уже остановлен. Поэтому именно в этом случае остановка в деструкторе лишняя
Понятно. Но FreeOnTerminate тут вообще лишний (т.к. вечный цикл). И я когда это писал даже вообразить не мог, что этот поток FreeOnTerminate.
...
Рейтинг: 0 / 0
74 сообщений из 74, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как правильно заморозить поток из самого себя?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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