Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ограничение количества соединений с базой, на стороне клиента 
:(
    Опции темы
PointerToNil
Дата 24.8.2014, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



*


Профиль
Группа: Участник
Сообщений: 108
Регистрация: 17.6.2013

Репутация: 3
Всего: 6



Цитата(drkot @  24.8.2014,  22:50 Найти цитируемый пост)
ивенты для того, чтоб 100500 потоков не крутили один и тот же цикл в ожидании освободившегося объекта. Как то так.
если 100500 потоков вызовут Event.WaitFor, то все они как бы "приостановятся". но ведь системный код (WaitForSingleObject), исполняющийся при этом в контексте каждого из потоков отдельно (т.е. в числе 100500 экземпляров), будет при этом что-то делать! есть веские подозрения, что таки крутить цикл (скорее всего, тоже со sleep-ом или подобным) - иных вариантов просто нет
PM MAIL   Вверх
drkot
Дата 25.8.2014, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



Цитата(PointerToNil @  25.8.2014,  00:49 Найти цитируемый пост)
иных вариантов просто нет

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


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
PointerToNil
Дата 25.8.2014, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



*


Профиль
Группа: Участник
Сообщений: 108
Регистрация: 17.6.2013

Репутация: 3
Всего: 6



Цитата(drkot @  25.8.2014,  14:11 Найти цитируемый пост)
сознается некая очередь потоков, и как минимум крутится один цикл, а скорее всего все висит на аппаратном прерывании таймера. Следовательно нулевое потребление ресурсов. 
думается, всё это - часть функциональности sleep() (т.е. по крайней мере должна и в нем быть, а у меня он есть)
(halt + аппаратное прерывание таймера - применимо только для того редчайшего случая, когда ВСЕ потоки вызовут sleep)
PM MAIL   Вверх
drkot
Дата 25.8.2014, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


Профиль
Группа: Завсегдатай
Сообщений: 1042
Регистрация: 5.5.2006

Репутация: 5
Всего: 8



PointerToNil,  предлагаю сделать тест и посмотреть.
Пул из 15 объектов и 50 потоков. После захвата объекта поток спит 100мс.
в качестве оценочных параметров можно считать: среднее время ожидания захвата, количество захватов (каждым потоком), количество отказов в захвате.


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
Sajtran
Дата 28.8.2014, 07:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 15.10.2008
Где: Мегион

Репутация: 2
Всего: 2



спс, PointerToNil, ваша 
Код

(try_count: integer = -1)

заметил у себя фигню, ивенты просто не работали (не ждали :-() 

drkot, я не думаю что сильно стоит бояться FreeLock-код. Вот, например, зачем состояния хранить, если можно объект просто изъять

вот подправка
Код

unit ResPools;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils,SyncObjs;

type

  { ResourcePool }

  generic ResourcePool<TObj>=class(TObject)
   private
    Event:TEventObject;
    Objs:array of TObj;
    FUseCount:integer;
    function GetSize: integer;inline;
    function GetWaitCount: integer;
   public
    constructor Create(ACount:integer);
    destructor Destroy;override;
    function Lock(Timeout : Cardinal=-1):TObj;
    procedure Unlock(const O:TObj);
    property WaitCount:integer read GetWaitCount;
    property UseCount:integer read FUseCount;
    property Size:integer read GetSize;
  end;


implementation

{ ResourcePool }

function ResourcePool.GetWaitCount: integer;
begin
  Result:=FUseCount-Size;
  if Result<0 then Result:=0;
end;

function ResourcePool.GetSize: integer;
begin
  Result:=Length(Objs);
end;

constructor ResourcePool.Create(ACount: integer);
var i:integer;
begin
  inherited Create;
  Event:=TEventObject.Create(nil,false,false,'');
  SetLength(Objs,ACount);
  for i:=0 to ACount-1 do begin
    Objs[i]:=TObj.Create;
  end;

end;

destructor ResourcePool.Destroy;
var i:integer;
begin
  for i:=0 to Size-1 do begin
    FreeAndNil(Objs[i]);
  end;
  FreeAndNil(Event);
  inherited Destroy;
end;

function ResourcePool.Lock(Timeout: Cardinal): TObj;
var i:integer;
  b:boolean;
begin
  b:=false;
  repeat
    if InterLockedIncrement(FUseCount)>Size then begin
      //если ожидающих больше, просто ждём нашего события и может нам повезёт
      b:=true;
      Event.WaitFor(Timeout);
    end;
    for i:=Size-1 downto 0 do begin
      Result:=Objs[i];
      if Result=nil then continue;// если удалось поменять на nil значит можно выйти с ним
      if InterlockedCompareExchange(Pointer(Objs[i]),nil,Pointer(Result))=Pointer(Result) then exit;
    end;

    InterLockedDecrement(FUseCount);
  until (Timeout>=0)and b;
  Result:=nil;
end;

procedure ResourcePool.Unlock(const O: TObj);
var i:integer;
begin
  for i:=Size-1 downto 0 do begin
    //если удалось заменить (т.е. там было пусто), то мы его вернули
    if InterlockedCompareExchange(Pointer(Objs[i]),Pointer(O),nil)=nil then break;
  end;
  InterLockedDecrement(FUseCount); //здесь подправил так надёжнее всё таки
  //if InterLockedDecrement(FUseCount)>=Size then
    Event.SetEvent;
end;

end.


вот так проверял


Код

program TestPool;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, ResPools;
type
  TPool=specialize ResourcePool<TObject>;

  { TTestThread }

  TTestThread=class(TThread)
   protected
     procedure Execute;override;
     constructor Create(ASuspended:boolean);
     destructor Destroy;override;

  end;
var
  Pool:TPool;
  ThreadCount:integer;
  { TTestThread }

procedure TTestThread.Execute;
var O:TObject;
  i:integer;
begin
  FreeOnTerminate:=true;
  for i:=1 to 1 do begin
    O:=Pool.Lock();
    try

      Sleep(1000);
    finally
      Pool.Unlock(O);
    end;

  end;

end;

constructor TTestThread.Create(ASuspended: boolean);
begin
  InterLockedIncrement(ThreadCount);
  inherited Create(ASuspended);
end;

destructor TTestThread.Destroy;
begin
  InterLockedDecrement(ThreadCount);
  inherited Destroy;
end;

var i:integer;
begin
  Pool:=TPool.Create(10);
  try
    for i:=1 to 150 do begin
      TTestThread.Create(false);
    end;
    repeat
      sleep(500);
      Writeln('Use=',Pool.UseCount,'  wait=',Pool.WaitCount);
    until ThreadCount=0;
    Writeln('Ok');
  finally
    Pool.Free;
  end;
end.




Это сообщение отредактировал(а) Sajtran - 28.8.2014, 08:11
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0906 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.