Сравнить функцию и многопоточность - PullRequest
2 голосов
/ 01 апреля 2009

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

procedure SortKeyList (KeyList : TList <Integer>; Inverted : Boolean);

, который берет список ключей и сортирует его. Процедура использует реализацию быстрой сортировки RTL TList.Sort:

KeyList.Sort (TComparer <Integer>.Construct (CompareKeys))

Теперь о проблеме: CompareKeys должен получить доступ к некоторым членам класса, чтобы отсортировать список (вот и весь смысл этого класса) Но RTL требует, чтобы CompareKeys были нормальной функцией. Как передать данные из объекта в функцию CompareKeys потокобезопасным способом? Очевидно, что использование глобальных переменных обмена не вариант, так как он ни в коем случае не является потокобезопасным.

Есть идеи по этому поводу?

Ответы [ 2 ]

4 голосов
/ 01 апреля 2009

Тот факт, что вы передаете CompareKeys в TComparer.Construct, означает, что CompareKeys не должна быть нормальной функцией. Delphi 2009 представил ссылки на методы , которые могут ссылаться на обычные функции, методы и анонимные методы. Я предполагаю, что TComparer.Construct создает ссылку на метод из обычной функции, которую вы ему даете. (Хотя я не уверен, почему; я думал, что компилятор сделал это преобразование автоматически.)

Предположим, у вас есть функция с тремя аргументами, которая получает список и два элемента для сравнения:

function CompareKeys(List: TList<Integer>; Item1, Item2: Integer): Integer;

Вы должны быть в состоянии передать анонимный метод примерно так:

KeyList.Sort(function(Item1, Item2: Integer): Integer;
  begin
    Result := CompareKeys(KeyList, Item1, Item2);
  end);
2 голосов
/ 01 апреля 2009

Возможно, вы могли бы использовать threadvar (локальная переменная потока) для хранения ссылки на ваш экземпляр, к которой затем можно получить доступ из функции CompareKeys (назначить threadvar непосредственно перед вызовом Sort).

...