Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.12.2011, 15:33   #1
Delphi_ProGer
Форумчанин
 
Регистрация: 30.10.2010
Сообщений: 524
Вопрос Наработки пула потоков

Здраствуйте форумчане!
Мог бы кто-нибудь поделиться своим пулом потоков(статическим)?

Извините что вопрос выглядит наглым, просто уже наверное вторую неделю пытаюсь сделать пул поток, но не получаеться
Если что, могу скинуть то, что у меня сейчас получаеться.
Delphi_ProGer вне форума Ответить с цитированием
Старый 29.12.2011, 21:40   #2
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Я бы делал так:
1. Главный класс пула потоков. В конструкторе число созданных потоков. Метод взятия свободного потока с указанием процедуры для Execute, которую поток должен делать. Метод сбора всех отработавших потоков обратно в пул.
2. Класс рабочего потока.

Ну и обрабатывать внештатные ситуации, сервисные функции (текущее число заняных потоков, процент использования пула и т.п.)
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 29.12.2011, 23:37   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вот же описание обьектного пула: http://ru.wikipedia.org/wiki/Объектный_пул
Создать можно на основе TList из contrs.pas
Человек_Борща вне форума Ответить с цитированием
Старый 30.12.2011, 02:19   #4
Delphi_ProGer
Форумчанин
 
Регистрация: 30.10.2010
Сообщений: 524
По умолчанию

Вот что у меня есть на даный момент. Пожалуйста, помогите протестировать и довести к стабильной работе. Сейчас проблема есть когда потоков меньше, чем задач, а также приостановление потока(процедура Execute)

Код:
unit ThreadPool;
interface
uses Classes, ExtCtrls, dialogs,windows;
 
Type
TDWorkProc = procedure();
TDOnDoneEvent = procedure(ThreadId: Word);
TDOnErrorEvent = procedure(ThreadId: Word);
 
TDThread = class(TThread)
    private
      HasJob: Boolean;
      Param: Pointer;
    protected
      procedure Execute; override;
    public
      OnWorkProc: TDWorkProc;
      OnDone: TDOnDoneEvent;
      OnError: TDOnErrorEvent;
end;
 
TDPool = class
    private
     Threads: array of TDThread;
     TaskList: TList;
     fPriority: TThreadPriority;
     fSize: Word;
     OnWork: TDWorkProc;
    function GetPriority: TThreadPriority;
    function GetSize: Word;
    procedure SetPriority(const Value: TThreadPriority);
    procedure SetSize(const Value: Word);
    function GetJobsCount: Word;
    function UpdatePool(Sender: TObject): Boolean;
 
    protected
 
    public
     Suspended: Boolean;
     OnWorkDone: TDOnDoneEvent;
     OnError: TDOnErrorEvent;
     property Priority: TThreadPriority read GetPriority write SetPriority;
     property Size: Word read GetSize write SetSize default 20;
     Procedure Start;
     Procedure Pause;
     Procedure Stop;
     Constructor Create(aSize: word=20);
     Destructor Destroy; override;
     Procedure AddTask(ThreadProc: TDWorkProc);
     Procedure DeleteTask(Index: Integer);
 
  end;
{*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*}
 
implementation
 
uses SysUtils;
Var
  ActiveJobs: Word=0;
  aSelf: TObject;
 
{ TPool }
 
Procedure TDPool.AddTask(ThreadProc: TDWorkProc);
var i: Word;
begin
  if (ActiveJobs=Size)or(Suspended=True) then //якщо всі потоки працюють,
    begin                 //чи пул призупинений, то...
      TaskList.Add(@ThreadProc);//додамо у чергу робіт!
    end
  else
    begin
     for i:=0 to Size-1 do
       if not(Threads[i].HasJob) then
       begin
         Threads[i].OnWorkProc:=ThreadProc;
         Threads[i].OnDone:=OnWorkDone;
         Threads[i].OnError:=OnError;
         Threads[i].HasJob:=True;
         Threads[i].Resume;
         Break;
       end;
     Inc(ActiveJobs);
    end;
end;
 
constructor TDPool.Create(aSize: word=20);
var i:word;
begin
  aSelf := Self;
  Size := aSize;
  ActiveJobs:=0;
  SetLength(Threads, Size);
  for i:=0 to Size-1 do
  begin
    Threads[i]:=TDThread.Create(True);
    Threads[i].Priority:=tpLowest;
  end;
  TaskList:=TList.Create;
  //*
  Suspended:=False;
end;
 
Procedure TDPool.DeleteTask(Index: Integer);
begin
 
end;
 
destructor TDPool.Destroy;
begin
  Stop;
  FreeAndNil(TaskList);
end;
 
function TDPool.GetJobsCount: Word;
begin
  Result := ActiveJobs;
end;
 
function TDPool.GetPriority: TThreadPriority;
begin
  Result:= fPriority;
end;
 
function TDPool.GetSize: Word;
begin
  Result := fSize;
end;
 
function TDPool.UpdatePool(Sender: TObject): Boolean;
var i: Word;
begin
  //update the thread's jobs
with TaskList do
begin
  if Count>0 then
    for i := 0 to Size-1 do
      if not(Threads[i].HasJob) then
       begin
         Threads[i].OnWorkProc:=Items[Count-1];
         Threads[i].OnDone:=OnWorkDone;
         Threads[i].OnError:=OnError;
         Threads[i].HasJob:=True;
         Delete(Count-1);
         Pack;
         Break;
         ResumeThread((aSelf as TDThread).Handle);
       end
 
  else
 ResumeThread((aSelf as TDThread).Handle);
end;
end;
 
procedure TDPool.Pause;
var i: Word;
begin
  for i:=0 to Size-1 do
    Threads[i].Suspend;
end;
 
 
procedure TDPool.SetPriority(const Value: TThreadPriority);
var i: Word;
begin
  for i:=Low(Threads) to High(Threads) do
    Threads[i].Priority:=Value;
end;
 
procedure TDPool.SetSize(const Value: Word);
begin
  if Value>500 then
    fSize := 500
  else
  if Value=0 then
    fSize := 10
  else
    fSize := Value;
end;
 
procedure TDPool.Start;
var i: Word;
begin
 for i:=0 to Size-1 do
   if (Threads[i].HasJob) and (Threads[i].Suspended) then
     Threads[i].Resume;
end;
 
procedure TDPool.Stop;
var i: Word;
begin
 for i:=0 to Size-1 do
   if (Threads[i].HasJob) and not(Threads[i].Suspended) then
     Threads[i].Terminate;
end;
 
{ TDThread }
procedure TDThread.Execute;
begin
  inherited;
while not Terminated do
  begin
    if Assigned(OnWorkProc) then
  try
    OnWorkProc;
    if Assigned(OnDone) then
    OnDone(Self.ThreadID);
    Self.HasJob := False;
  except
    if Assigned(OnError) then
      OnError(Self.ThreadID);
  end;
    Dec(ActiveJobs);
    OnWorkProc:=nil;
    (aSelf as TDPool).UpdatePool(aSelf);
    Sleep(100);
  end;
end;
 
end.
Delphi_ProGer вне форума Ответить с цитированием
Старый 30.12.2011, 19:18   #5
Delphi_ProGer
Форумчанин
 
Регистрация: 30.10.2010
Сообщений: 524
По умолчанию

Цитата:
Сообщение от Человек_Борща Посмотреть сообщение
Создать можно на основе TList из contrs.pas

что за contrs?? у меня нет такого. Delphi 7
Delphi_ProGer вне форума Ответить с цитированием
Старый 31.12.2011, 19:43   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

contrs в общем как-то так. Этот модуль есть в delphi 7. Точнее посмотрите в справке. Там сложно-стрёмное имя.

У пула потоков есть 2 списка:
1. Активные потоки: те которые заняты работой.
2. Ожидающие потоки: те которые ожидают работу.
Сам пул потоков это TObject. Его списки это TList.

Кроме того, у вас вообще не пул потоков. В пуле потоков, число объектов постоянно. Завершенные потоки должны обнулиться, но не уничтожится, и переместиться в список ожидающих потоков.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
наработки по сетевой игре sashonk Gamedev - cоздание игр: Unity, OpenGL, DirectX 0 29.08.2010 00:09
Часы(есть наработки) sllh_111 Помощь студентам 2 19.04.2010 17:04
Наработки... CodeExpert Фриланс 2 15.04.2010 11:50
Pascal, наработки есть. Otre4eHHbIu Помощь студентам 1 24.12.2009 08:43