代码之家  ›  专栏  ›  技术社区  ›  Tom

全局钩子线程占用太多CPU,如何修复?

  •  3
  • Tom  · 技术社区  · 12 年前

    以下全局Hook线程占用了太多CPU,除非我在那里添加Sleep(10), 除了睡眠(10ms),还有其他解决方案吗?睡眠看起来并不是我的应用程序性能的最佳解决方案。如果我加了太多的睡眠,不是也会减缓鼠标的速度吗。

      procedure THookThread.Execute;
        begin
          hookhandle := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseHook, Hinstance, 0);
    
         while not Terminated do
          begin    
            MessageLoop;
          //  Sleep(10);
          end;
    
          UnHookWindowsHookEx(hookhandle);
          hookhandle := 0;
    
        end;
    
    procedure THookThread.MessageLoop;
    var
      msg: TMsg;
    begin
      while PeekMessage(msg, 0, 0, 0, PM_NOREMOVE) do
      begin
        TranslateMessage(msg);
        DispatchMessage(msg);
      end;
    end;
    
    2 回复  |  直到 12 年前
        1
  •  6
  •   David Heffernan    12 年前

    您的消息循环是忙循环。你应该使用 GetMessage 而不是 PeekMessage 。那是因为 获取消息 块,直到消息被添加到队列。

    你在评论中注意到 获取消息 中断终止代码的块。通过在终止线程后向线程发布消息来解决这个问题 WM_NULL 作为一般唤醒,或 WM_QUIT 作为退出消息循环的显式指令。

        2
  •  5
  •   Remy Lebeau    12 年前

    请尝试更类似的方法:

    procedure THookThread.Execute;
    var
      msg: TMsg;
      ret: LongInt;
    begin
      //create the message queue...
      PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
    
      hookhandle := SetWindowsHookEx(WH_MOUSE_LL, @LowLevelMouseHook, Hinstance, 0);
      if hookhandle = 0 then RaiseLastOSError; 
    
      try
        while GetMessage(msg, 0, 0, 0) and (not Terminated) do
        begin
          TranslateMessage(msg);
          DispatchMessage(msg);
        end;
      finally
        UnHookWindowsHookEx(hookhandle);
        hookhandle := 0;
      end;
    end;
    
    procedure THookThread.Stop;
    begin
      Terminate;
      PostThreadMessage(ThreadID, WM_QUIT, 0, 0);
    end;