Sunday, April 17, 2011

Compare Function and Multithreading

Assume a multi-threaded environment and a (properly synchronized) class that has one particular procedure

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

that takes a list of keys and sorts it. The procedure uses the RTL quicksort implementation TList.Sort:

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

Now for the problem: CompareKeys has to access some members of the class in order to sort the list (that's the whole point about this class). But the RTL requires CompareKeys to be a normal function. How can I pass data from the object to the CompareKeys function in a thread-safe manner? Obviously using global exchange variables isn't an option since it is in no way thread-safe.

Any ideas on that?

From stackoverflow
  • Perhaps you could use a threadvar (thread local variable) to hold a reference to your instance which could then be accessed from the CompareKeys function (assign the threadvar just before calling Sort).

    Smasher : +1 thanks, that should work!
  • The fact that you're passing CompareKeys to TComparer.Construct means that CompareKeys doesn't have to be a normal function. Delphi 2009 introduced method references, which can refer to ordinary functions, methods, and anonymous methods. I assume TComparer.Construct constructs a method reference out of the ordinary function you give it. (I'm not sure why, though; I thought the compiler did that conversion automatically.)

    Suppose you have a three-argument function that receives a list and the two items to compare:

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

    You should be able to pass an anonymous method something like this:

    KeyList.Sort(function(Item1, Item2: Integer): Integer;
      begin
        Result := CompareKeys(KeyList, Item1, Item2);
      end);
    
    Smasher : +1 great answer. Anonymous methods with their capability to access the calling context give me exactly what I need! Haven't thought of that! Thank you very much!

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.