Как программировать количество Ваших потоков в Delphi

Таким образом, вот проблема, измените размеры, звонит, вставляют, который делает, конструкция копии от значения по умолчанию создала элемент для каждого из недавно добавленных элементов. Для получения этого к 0 стоимости, необходимо записать собственного конструктора по умолчанию И собственного конструктора копии как пустые функции. Выполнение этого Вашему конструктору копии очень плохая идея , потому что это повредит станд.:: внутренние алгоритмы перераспределения вектора.

Сводка: Вы не собираетесь быть способными сделать это со станд.:: вектор.

6
задан mghie 29 September 2009 в 14:11
поделиться

3 ответа

Я бы создал абстрактный класс TTask. Этот класс предназначен для выполнения задачи. С помощью метода Execute:

type

  TTask = abstract class
  protected
    procedure DoExecute; virtual; abstract;
  public
    procedure Execute;
  end;

  TTaskThread = class (TThread)
  private
    FTask : TTask;
  public
    constructor Create(const ATask: TTask); 
    // Assigns FTask and enables thread, free on terminate.

    procedure Execute; override; // Calls FTask.Execute.
 end;

Метод Execute проверяет количество потоков. Если максимум не достигнут, он запускает поток, используя TTaskThread, который вызывает DoExecute и, таким образом, выполняет задачу в потоке. Если достигается максимум, DoExecute вызывается напрямую.

5
ответ дан 10 December 2019 в 02:50
поделиться

Ответ Gamecat хорош в том, что касается абстрактного класса задач, но я думаю, что вызов DoExecute () для задачи в вызывающем потоке (как это делает сама статья) тоже) - плохая идея. Я всегда ставил задачи в очередь для выполнения фоновыми потоками, если только потоки не были отключены полностью, и вот почему.

Рассмотрим следующий (надуманный) случай, когда вам нужно выполнить три независимых процедуры, связанных с процессором:

Procedure1_WhichTakes200ms;
Procedure2_WhichTakes400ms;
Procedure3_WhichTakes200ms;

Для лучше использовать вашу двухъядерную систему, если вы хотите выполнять их в двух потоках. Вы должны ограничить количество фоновых потоков до одного, так что с основным потоком у вас будет столько же потоков, сколько и ядер.

Теперь первая процедура будет выполняться в рабочем потоке и завершится через 200 миллисекунд. Вторая процедура начнется немедленно и будет выполняться в основном потоке, поскольку единственный настроенный рабочий поток уже занят, и завершится через 400 миллисекунд. Тогда последняя процедура будет выполнена в рабочем потоке, который уже спал 200 миллисекунд и завершится через 200 миллисекунд. Общее время выполнения 600 миллисекунд, и в течение 2/3 этого времени только один из обоих потоков действительно выполнял значимую работу.

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

Теперь рассмотрим распространенный способ использования пула потоков. В соответствии с конфигурацией вы должны ограничить количество потоков в пуле до 2 (количество ядер), использовать основной поток только для планирования потоков в пуле, а затем дождаться завершения всех задач. С приведенной выше последовательностью задач в очереди поток 1 возьмет на себя первую задачу, поток 2 - вторую задачу. Через 200 миллисекунд первая задача будет завершена, и первый рабочий поток возьмет третью задачу из пула, который потом пуст. Через 400 миллисекунд и вторая, и третья задача будут завершены, и основной поток будет разблокирован. Общее время выполнения 400 миллисекунд при 100% нагрузке на оба ядра за это время.

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

4
ответ дан 10 December 2019 в 02:50
поделиться

Обычно у меня есть только один класс, наследующий от TThread, тот, который принимает «рабочие элементы» из очереди или стека и приостанавливает их, когда больше нет доступных элементов. Затем основная программа может решить, сколько экземпляров этого потока нужно создать и запустить. (с использованием этого значения конфигурации).

Эта «очередь рабочих элементов» также должна быть достаточно умной, чтобы возобновлять приостановленные потоки или создавать новый поток, когда это необходимо (и когда это позволяет ограничение), когда рабочий элемент находится в очереди или поток завершил обработку предмета рабочего.

0
ответ дан 10 December 2019 в 02:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: