Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Обход ошибки `EMonitorLockException` при использовании `TTask.WaitForAny` в Delphi

Delphi , Компоненты и Классы , Потоки

Вопрос, поднятый в данном запросе, касается использования новой библиотеки потоков в Delphi для выполнения задач параллельно с использованием метода TTask.WaitForAny() для получения первого результата. Однако, при использовании этого метода иногда возникает исключение EMonitorLockException с сообщением "Object lock not owned". В контексте вопроса уже содержится решение проблемы, а именно - обнаруженный баг в библиотеке потоков, связанный с использованием TMonitor и/или TTask.WaitForAny(). Пользователь пытался сократить код до минимума для воспроизведения ошибки, что подтверждает наличие бага. В качестве альтернативного ответа предложено использование TParallel.For для остановки выполнения при получении ответа, с использованием сигналов состояния параллельного цикла.

Подтвержденный ответ:

Использование TParallel.For позволяет остановить выполнение всех задач, как только одна из них выполнит условие остановки. В примере кода, представленном в альтернативном ответе, используется критическая секция для защиты переменных, которые могут быть изменены в параллельных потоках. Как только условие остановки выполнено, сигнал loopState.Stop останавливает все текущие и ожидающие итерации.

Пример кода на Object Pascal (Delphi):

procedure Parallel3(CS: TCriticalSection);
var
  Ticks: Cardinal;
  i, ix: Integer;
begin
  i := 0;
  Ticks := TThread.GetTickCount;
  TParallel.For(1, WorkerCount,
    procedure(index: Integer; loopState: TParallel.TLoopState)
    var
      k, l, m: Integer;
    begin
      // Сложные вычисления
      k := (1000 - index) * 1000;
      for l := 0 to Pred(k) do
        m := k div 1000;
      // Если условие остановки выполнено:
      CS.Enter;
      try
        if loopState.Stopped then // Результат уже найден
          Exit;
        loopState.Stop;  // Сигнал остановки
        Inc(i);
        ix := index;
      finally
        CS.Leave;
      end;
    end);
  Ticks := TThread.GetTickCount - Ticks;
  WriteLn('Parallel time ' + Ticks.ToString + ' ticks', ' i :', i, ' index:', ix);
end;

Обратите внимание, что в критической секции CS защищаются переменные i и ix. После выполнения условия остановки, все итерации параллельного цикла должны быть остановлены, и текущие итерации проверяют состояние loopState.Stopped.

Альтернативное решение с использованием OTL:

Автор альтернативного ответа выразил опасения относительно текущего состояния библиотеки System.Threading, рекомендуя использовать альтернативный фреймворк OTL. Для остановки выполнения задач в OTL можно использовать cancelToken.Signal для установки сигнала остановки и cancelToken.IsSignaled для проверки состояния.

Заключение:

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

Создано по материалам из источника по ссылке.

Пользователь столкнулся с исключением `EMonitorLockException` при использовании библиотеки потоков в Delphi для параллельных вычислений и нашел решение проблемы в виде бага, связанного с использованием `TMonitor` и `TTask.WaitForAny


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-13 19:13:28/0.003615140914917/0