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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2014, 21:12   #1
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
По умолчанию Автоматическая очередь потоков

Как сделать очередь, подобной Dоwnlоаd Маstеr?
Например:
_всего(Max) активных потоков разрешено ~5
_на запуск потоков всего ~15
_как освободилось место, запускаются следующие потоки, пока не закончатся те, которые отмечены на закачку

В реальном модуле потока используется sslHTTPCLi или idHTTP.
Интересует только очередь.

Вложение: простой пример для отладки
Вложения
Тип файла: rar Virtual TreeView progressbar.rar (491.4 Кб, 20 просмотров)
Alter вне форума Ответить с цитированием
Старый 10.03.2014, 22:41   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Запустить первые 5. Поток сообщает о своем завершении - запускается следующий, если есть что запускать
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 10.03.2014, 22:58   #3
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Семафоры, ИМХО, самое то.
Код из Button3Click нужно вынести в отдельный поток и добавить туды семафоры. Примерно так
Код:
  
mySem := CreateSemaphore(nil, 4, 4, 'my_unikal_name_7523457374');//глобальная переменная
  if VST1.RootNodeCount <= 0 then Exit;
  aNode := VST1.RootNode.FirstChild;
  while aNode <> nil do
  begin
    ProcMessages;
    Thr := TMyThread.Create(aNode, VST1.GetNodeData(aNode), Handle, True);
    Thr.Resume;
    aNode := aNode.NextSibling;
    WaitForSingleObject(mySem, INFINITE);
  end;
В деструктор потока Thr добавить освобождение семафора
Код:
ReleaseSemaphore(mySem, 1, nil);
Если форма не нужна во время работы потоков (включая моменты синхронизации), то отдельный поток можно не заводить - форма просто подвиснет

Последний раз редактировалось eoln; 10.03.2014 в 23:08.
eoln вне форума Ответить с цитированием
Старый 12.03.2014, 18:40   #4
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,183
По умолчанию

Без дополнительного потока получилось.
Код:

var
  mySem :THandle;
  ActivThrCount :Integer; // потоков активно
  procedure DelThr(Thrd :TMyThread);
  procedure CreateSemMax(N :Byte=4);
  ...

implementation

procedure DelThr(Thrd :TMyThread);
var
  I :Integer;
begin
  with ThrList.LockList do
    try
  for I := 0 to Count-1 do
  begin
    try
      if TMyThread(Items[I]) = Thrd then
      begin
        ProcMessages;
        if Assigned(Items[I]) then
         TMyThread(Items[I]).Reliase; // Free
        Delete(I);
        Break;
      end;
    except
    end;
  end;
    // sem
  If Count <= 0 then
   CloseHandle(mySem);
    finally
  ThrList.UnlockList;
    end;
end;

procedure CreateSemMax(N :Byte);
begin // переменная глобальная
  mySem := CreateSemaphore(nil, N, N, 'my_unikal_name_7523457374');
end;

procedure TMyThread.Execute;
begin // Анимация
   try
 AddThr(Self);
 WaitForSingleObject(mySem, INFINITE);
 Synchronize(
    procedure
    begin
      Inc(ActivThrCount);
    end
            );
 while not Terminated do
 begin
     try
   if Terminated then Break;
   Synchronize(CheckDeleted);
   If fData^.CupPosI >= fData^.MaxI then
    fData^.CupPosI := 0;
   fData^.CupPosI := fData^.CupPosI + 1;
   Synchronize(RepaintTree);
   Sleep(Random(400));
     finally
   if fData^.CupPosI >= fData^.MaxI then
    Terminate;
     end;
 end;
   finally
  DelThr(Self);
 Synchronize(
    procedure
    begin
      Dec(ActivThrCount);
    end
            );
   end;
end;

procedure TMyThread.Reliase;
begin
 ReleaseSemaphore(mySem, 1, nil);
 FreeOnTerminate := True; 
 Terminate;
 Resume;                  // Будим поток для завершения
end;

...

initialization
  ActivThrCount := 0;
...
В процессе работы потоков, без перезапуска потоков, возможно ли уменьшать и прибавлять число разрешенных потоков? Как например в Dоwnlоаd Маstеr и т.п.
Изображения
Тип файла: png GUI_02.png (61.7 Кб, 299 просмотров)
Вложения
Тип файла: zip Virtual TreeView progressbar 2.zip (488.9 Кб, 23 просмотров)

Последний раз редактировалось Alter; 12.03.2014 в 18:43.
Alter вне форума Ответить с цитированием
Старый 13.03.2014, 00:09   #5
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Да, можно просто манимулировать счётчиком.
Создать семафор например, на 1000, а начальный индекс задать на 996. Что-то вроде
Код:
mySem := CreateSemaphore(nil, 1001-N, 1000, 'my_unikal_name_7523457374');//N>0
Если надо увеличить число потоков на M штук, то просто вызываем
Код:
ReleaseSemaphore(mySem, M, nil);
А вот чтобы уменьшить, наверное, придётся M раз вызвать WaitForSingleObject. Правда при таком раскладе (когда запущены все потоки, но некоторые ждут) неизвестно выполнятся ли эти WaitForSingleObject первее тех WaitForSingleObject, которые ожидают в потоках. А значит снижение числа потоков в худшем случае может и не произойти до самого последнего момента.
Можно другой вариант - в TMyThread.Execute сразу после WaitForSingleObject вызывать ф-ию, которая проверяет не превышает ли число активных потоков разрешённого значения, и если это так, то в этом же потоке снова выполняется WaitForSingleObject. Но, ИМХО, костылями попахивает И этот костыль надо обернуть в критичискую секцию, например

Последний раз редактировалось eoln; 13.03.2014 в 00:12.
eoln вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вводим 15 элементов в очередь, затем выводим на экран эту очередь и добавил в очередь еще один элемент. Потом удаляем любой элемен Xumera C++ Builder 2 07.12.2013 13:56
Автоматическая сортировка Proton-x Microsoft Office Excel 1 06.02.2013 22:09
автоматическая загрузка js в IE world12_tk JavaScript, Ajax 3 03.06.2011 18:41
Автоматическая регистрация stepennwolf PHP 2 21.08.2010 20:39
Автоматическая группировка anester Microsoft Office Excel 0 08.06.2010 14:07