Self Suspending a thread in Delphi when it's not needed and safely resuming

前端 未结 3 1651
萌比男神i
萌比男神i 2020-12-19 05:20

This question involves Delphi and XE specifically deprecating Suspend and Resume. I have read other posts and I have not found a similar usage so far, so I’m going to go ahe

相关标签:
3条回答
  • 2020-12-19 05:53

    Instead of suspending the thread, make it sleep. Make it block on some waitable handle, and when the handle becomes signalled, the thread will wake up.

    You have many options for waitable objects, including events, mutex objects, semaphores, message queues, pipes.

    Suppose you choose to use an event. Make it an auto-reset event. When the queue is empty, call the event's WaitFor method. When something else populates the queue or wants to quit, have it call the event's SetEvent method.

    I preferred technique is to use the OS message queue. I'd replace your queue object with messages. Then, write a standard GetMessage loop. When the queue is empty, it will automatically block to wait for a new message. Turn a termination request into just another message. (The TThread.Terminate method simply isn't a very useful function once you start doing anything interesting with threads because it's not virtual.)

    0 讨论(0)
  • 2020-12-19 05:58

    I'd recommend the following implementation of TthrdQueue:

    type
      TthrdQueue = class(TThread)
      private
        FEvent: THandle;
      protected
        procedure Execute; override;
      public
        procedure MyResume;
      end;
    
    implementation
    
    procedure TthrdQueue.MyResume;
    begin
      SetEvent(FEvent);
    end;
    
    procedure TthrdQueue.Execute;
    begin
      FEvent:= CreateEvent(nil,
                           False,    // auto reset
                           False,    // initial state = not signaled
                           nil);
      FreeOnTerminate := true;
      try
        while not Terminated do begin
          if not Queue.Empty then begin
            Obj :=  Pop();
            MyProcess(Obj);  //Do work
            Obj.Ready := true;
          end
          else
            WaitForSingleObject(FEvent, INFINITE);  // No more Work
        end;
      finally
        CloseHandle(FEvent);
      end;
    end;
    
    0 讨论(0)
  • 2020-12-19 06:16

    There is a library to allow implementation of producer-consumer queue in Delphi using condition variables. This scenario is actually the example discussed.

    The classic example of condition variables is the producer/consumer problem. One or more threads called producers produce items and add them to a queue. Consumers (other threads) consume items by removing the produced items from the queue.

    0 讨论(0)
提交回复
热议问题