Delphi 中 CPU 使用率 100%

发布于 2024-07-13 07:55:59 字数 616 浏览 4 评论 0原文

我使用 Indy 9 和 Delphi 5。在我的应用程序中,我想通过 UDP 与网络设备通信。 所以我使用UDPServer comp。 在从 TThread 派生的类中。 当我编写类似以下代码时,CPU 使用率为 100%。

在线程中:

while not terminated do begin
  if GetMessage(Msg, 0, 0, 0) then begin
    if Msg.message = WM_UDPMSG then
      Break
    else
      DispatchMessage(Msg);
  end;
end;

和 OnUDPRead 事件:

  try    
    // Processing the data here
  except
    PostThreadMessage(ThreadId, WM_UDPMSG, 0, 0);
  end;

当我在 while-do 循环或 OnUDPRead 事件中使用 Sleep 函数时,没有任何变化。 CPU使用率仍然是100%。

我的线程优先级是正常。

我该如何解决我的问题?

I use Indy 9 with Delphi 5. In my application I want to communicate with a network device via UDP. So I use UDPServer comp. in a class which is derived from TThread.
When I write similar to the following code then CPU usage is 100%.

in the thread :

while not terminated do begin
  if GetMessage(Msg, 0, 0, 0) then begin
    if Msg.message = WM_UDPMSG then
      Break
    else
      DispatchMessage(Msg);
  end;
end;

and OnUDPRead event :

  try    
    // Processing the data here
  except
    PostThreadMessage(ThreadId, WM_UDPMSG, 0, 0);
  end;

When I use Sleep function in the while-do loop or in OnUDPRead event there is no change. Still the CPU usage is 100%.

My thread priority is Normal.

How can I solve my problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

叹倦 2024-07-20 07:55:59

您遇到的问题是因为您在 GUI 线程中接收 UDP 数据,但想要在另一个线程中处理该数据。

真正的问题是您尝试以阻塞方式使用异步组件。 更好的解决方案是使用真正的阻塞 UDP 通信库,例如 synapse 。 然后就很容易等待线程中接收新数据。

你可以这样写:

while not Terminated do
begin
  BytesRead := FSocker.RecvBufferEx(@(Buffer[0]), BufferSize, Timeout);
  if (BytesRead = 0) then
  begin
    // continue or exit if the receiving Failed
    case FSocket.LastError of
      0, WSAETIMEDOUT: Continue;
      WSAECONNRESET, WSAENETRESET,
        WSAENOTCONN, WSAECONNABORTED,
        WSAENETDOWN:
        begin
          CloseConnection;
          Exit;
        end;
    else
      CloseConnection;
      Exit;
    end;    
  end;
  // process the data in the buffer
end;

The problem you have is because you're receiving the UDP data in the GUI thread, but want to process the data in another thread.

The real problem is that your trying to use a asynchronous component in a blocking way. The better solution would be to use a real blocking UDP communication library such as synapse. Then it's very easy to just wait for new data to receive in your thread.

You could just write:

while not Terminated do
begin
  BytesRead := FSocker.RecvBufferEx(@(Buffer[0]), BufferSize, Timeout);
  if (BytesRead = 0) then
  begin
    // continue or exit if the receiving Failed
    case FSocket.LastError of
      0, WSAETIMEDOUT: Continue;
      WSAECONNRESET, WSAENETRESET,
        WSAENOTCONN, WSAECONNABORTED,
        WSAENETDOWN:
        begin
          CloseConnection;
          Exit;
        end;
    else
      CloseConnection;
      Exit;
    end;    
  end;
  // process the data in the buffer
end;
凉城凉梦凉人心 2024-07-20 07:55:59

我对delphi代码不熟悉,但是你正在运行busy-wait 正在磨你的CPU的机制。

在循环中引入睡眠或延迟只会隐藏问题。 我建议使用更好的方法来接收消息/事件。 存在许多解决方案,例如观察者-侦听器模式或线程等待和通知方案。


Some helpful links in response to your comment:

I'm not intimate with delphi code, but you are running a busy-wait mechanism which is grinding your CPU.

Introducing a sleep or a delay to the loop only hides the problem. I suggest using a better method for receiving your messages/events. Many solutions exist, like the observer-listener pattern, or thread wait and notify schemes.


Some helpful links in response to your comment:

装迷糊 2024-07-20 07:55:59

1 我认为您需要高于 9.0.0.18 的 Indy 版本。 较旧的有令人停止的线程错误。 其中包括随 Delphi 一起提供的 Indy 版本,直至版本 7。

2 查看有关如何使用 Indy 的示例代码。

http://www.indyproject.org/demos/index.html

1 You need a version of Indy newer than 9.0.0.18, I think. Older ones have show-stopping threading bugs. That includes all versions of Indy delivered with Delphi up to version 7.

2 Take a look at the sample code on how to work with Indy.

http://www.indyproject.org/demos/index.html

jJeQQOZ5 2024-07-20 07:55:59

是否有一个 GetMessage 版本可以等待(阻塞线程)直到消息到达?

Is there a version of GetMessage which waits (blocks the thread) until a message arrives?

怪我太投入 2024-07-20 07:55:59

我不知道 GetMassage 的版本。 但它在 Windows.pas 中声明如下

function GetMessage; external user32 name 'GetMessageA';

I don't know the verison of GetMassage. But it declared in Windows.pas like this

function GetMessage; external user32 name 'GetMessageA';
青巷忧颜 2024-07-20 07:55:59

这个项目是一个非常大的项目。 所以更新 Indy 对我来说很困难。 但如果你确定问题是因为旧版本的 Indy,我会更新它。

我看过所有印地演示。 这些演示非常简单。 在我的项目中,我的数据传输速度非常快。 (如实时录音机)

This project is very big project. So updating Indy is difficult for me. But if you sure the problem is because of old version of Indy, I'll update it.

I've looked at all Indy demos. These demos are very simple. In my project I've very fast data transfer. (Like real time sound recorder)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文