Исходный код цемафора Delphi

#delphi #semaphore #delphi-6

#delphi #семафор #delphi-6

Вопрос:

Я хочу создать пул потоков. Я нашел пару примеров в интернете, но они используют TSemaphore в библиотеке SyncObjs.

Я использую Delphi 6, и мой SyncObjs не включает Цемафор. Я просмотрел сеть и не могу найти для нее никакого исходного кода.

Существует ли библиотека, работающая с Delphi 6, которая включает TSemaphore?

Комментарии:

1. TSemaphore это простая оболочка вокруг объекта семафора Win32. Вы можете создать свой собственный класс, чтобы достаточно легко инкапсулировать это. Начните с документации MSDN.

2. На самом деле Win32 API также содержит реализацию пула потоков. Возможно, вы захотите использовать этот (или другой из OmmniThread), прежде чем изобретать велосипед (и исправлять все ошибки тоже. Правильно настроить пул потоков не так-то просто)

3. @Daniel, API пула потоков существует со времен Vista, и даже несмотря на то, что поддержка XP прекратилась, на нем все еще работает так много компьютеров.

4. @TLama: Это правильно. Но все еще возможно использовать OmmniThread (я думаю, что они поддерживают XP выше). Если у вас нет большого опыта в многопоточности, вы обязательно совершите серьезные ошибки (которые могут даже ухудшить производительность по сравнению с однопоточным выполнением …). И я даже не говорю о взаимоблокировках или оптимизации ресурсов

5. @Daniel, OmniThreadLibrary предназначен для D2007 и выше.

Ответ №1:

TSemaphore Класс представляет собой простую оболочку вокруг Win32 semaphore API. Очень легко создать простую оболочку в том же стиле. Например:

 type
  TSemaphore = class
  private
    FHandle: THandle;
  public
    constructor Create(AInitialCount, AMaximumCount: Integer);
    destructor Destroy; override;
    procedure Acquire;
    function Release(AReleaseCount: Integer): Integer; overload;
    procedure Release; overload;
  end;

constructor TSemaphore.Create(AInitialCount, AMaximumCount: Integer);
begin
  inherited Create;
  FHandle := CreateSemaphore(nil, AInitialCount, AMaximumCount, nil);
  Win32Check(FHandle <> 0);
end;

destructor TSemaphore.Destroy;
begin
  if FHandle <> 0 then
    CloseHandle(FHandle);
  inherited;
end;

procedure TSemaphore.Acquire;
begin
  Win32Check(WaitForSingleObject(FHandle, INFINITE) = WAIT_OBJECT_0);
end;

function TSemaphore.Release(AReleaseCount: Integer): Integer;
begin
  Win32Check(ReleaseSemaphore(FHandle, AReleaseCount, @Result));
end;

procedure TSemaphore.Release;
begin
  Release(1);
end;
  

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

Обратите внимание, что я не тестировал это, поэтому, пожалуйста, не копируйте это вслепую, не пытаясь понять.

Комментарии:

1. Спасибо, Дэвид, похоже, это отличное место для начала.