Есть 5 одинаковых потока в массиве потоков:
TReadThread = class(TThread)
private
protected
procedure Execute; override;
end;
.......
var
.......
ar: array[1..5] of TReadThread;
procedure TReadThread.Execute;
var
i,k : integer;
begin
// поток выполняет длинные по времени действия, например такие:
k := 0;
for i:=1 to 99999 do
k := k+1;
end;
Нужно организовать что-то вроде пула потоков. Например, при нажатии на кнопку проверятся массив потоков, находится первый незанятый поток и запускается на выполнение параллельно с остальными работающими потоками (после выполнения своих действий, поток не должен удаляться, а должен ждать поступления нового запроса на выполнение). Как это организовать? Как проверить незанятость потока? Если можно, то напишите маленький пример кода. Всем заранее спасибо.
Здравствуйте, C0nsul, Вы писали:
C>Как проверить незанятость потока?
Ну а в чем проблема? В потоке заводишь переменную Busy, которая, пока поток выполняет какую-то работу, устанавливается в True, а когда работа закончена — в False. Ну и для исключения одновременного доступа к переменной из данного потока (на запись) и извне его (на чтение) заворачиваешь ее в функции или в свойство.
TMyThread=class (TThread)
private
FBusy: boolean; //в Create устанавливается в True
csBusy: TCriticalSection; //в TMyThread.Create надо создать; Uses SyncObjs
procedure SetBusy(Value:boolean);
eNextTask: TEvent; //Uses SyncObjs; ManualReset ставим в False
public //вызываются извне потока
function IsBusy():boolean;
procedure NewTask(... параметры, определяющие следующую поставленную задачу ...);
//следует вызывать если не Busy
end;
finction TMyThread.IsBusy():boolean;
begin
csBusy.Enter();
result:=FBusy;
csBusy.Leaver();
end;
procedure TMyThread.Execute():boolean;
begin
Busy:=false;
repeat
eNextTask.WaitFor();
if Terminated then break;
//Выполняем поставленную задачу
until false;
end;
procedure TMyThread.NewTask(...):boolean;
begin
//Как-то запоминаем поставленную задачу
eNextTask.SetEvent();
end;
Что-то на эту тему.
Ну и потом пробегаем по всем потокам, смотрим, который из них не IsBusy(), ему и отдаем задание. Если все заняты, ждем N секунд и повторяем попытку. Хотя бы так.
А вообще, для этих целей можно, наверное, как-то использовать статью
Алексея Ширшова http://rsdn.ru/article/baseserv/threadpool.xmlАвтор(ы): Алексей Ширшов
Дата: 03.08.2003
Статья посвящена системным механизмам, организующим (или помогающим организовать) пул потоков. Рассматриваются базовые, универсальные сервисы, с помощью которых можно реализовывать серверы для любых доступных механизмов взаимодействия сервера и клиента: сокеты, именованные каналы (named pipes), почтовые ящики (mailslots) и проч.
Slicer