多线程问题

标签 multithreading delphi

1)这可能以前被问过很多次,我已经阅读了很多关于 SleepWaitForSingleObject 的内容,但仍然有点困惑。作为示例,我有一个简单的后台线程,从数据处理线程调用该线程以向用户显示一些消息,而不会阻塞数据处理线程。在这种情况下,就性能(CPU 使用率/CPU 时间)而言,哪个更好:http://pastebin.com/VuhfZUEghttp://pastebin.com/eciK92ze 我怀疑 sleep 时间越短,标志越多,性能就越差。另一方面, sleep 时间越长,性能会越好,但 react 延迟会增加,并且对于低端机器上的用户来说,如果线程很多, react 延迟最终会变得明显。那是对的吗?那么保持“休眠”、不活动线程的最佳方法是什么?

2) SetEvent 是阻塞 (SendMessage) 还是非阻塞 (PostMessage)?

3)在TForm.OnCreate事件中我有以下代码:

procedure TFormSubsystem.FormCreate(Sender: TObject);
begin
  Application.OnException:=LogApplicationException;
  Application.OnActivate:=InitiateApplication;
end;

procedure TFormSubsystem.LogApplicationException(Sender: TObject; E: Exception);
var
  ErrorFile: TextFile;
  ErrorInfo: String;
begin
  AssignFile(ErrorFile, AppPath+'Error.log');
  if FileExists(AppPath+'Error.log') then
    Append(ErrorFile)
  else
    Rewrite(ErrorFile);

    ErrorInfo:=DateTimeToStr(Now)+' Unhandled exception';
    if Assigned(Sender) then
      ErrorInfo:=ErrorInfo+' in '+Sender.UnitName+'->'+Sender.ClassName;
    ErrorInfo:=ErrorInfo+': '+E.Message;

  try
    WriteLn(ErrorFile, ErrorInfo);
  finally
    CloseFile(ErrorFile)
  end;
end;

这不是记录错误的最佳方式,但很简单。问题是:如果 TSomeThreadAncestor.Execute 内部或通过 Synchronize 调用的方法内部出现异常,会发生什么?

4) SynchronizeQueue 之间到底有什么区别?当我的后台线程与 GUI 交互时,我应该使用哪一个?我没有竞争条件并且已经使用了信号量之类的东西。

5) 使用这种结构安全吗?

procedure TShowBigDialoxBoxThread.Execute;
begin
  while ThreadNotTerminated do begin
    EventHandler.WaitFor(INFINITE);
    if not(ThreadNotTerminated) then
      Continue;
    EventHandler.ResetEvent;
    Synchronize(procedure begin
      MessageDlgBig(FMsg, FDlgType, FButtons, FHelpContext, FDefaultButton, FDlgMinWidth);
    end); // this kind of Synchronize call looks fishy
  end;
end;

或者我应该像上面提供的示例一样继续调用类方法吗?

编辑: 我目前使用Delphi XE5。

最佳答案

如果您可以使用阻塞函数进行等待,则在线程核心中进行轮询是一种不好的做法。您需要了解的是,上下文更改对于 CPU 使用率来说非常昂贵。当没有其他选择时,您应该进行轮询的唯一情况(无法通知您何时进行工作)。

<小时/>

区别如下:

投票:

您的线程通过调用“Sleep()”将控制权交给线程 Controller ,这会强制上下文更改。在给定的时间段(和一点)之后,线程 Controller 会将控制权交还给您的线程,启动另一个上下文更改。您的线程检查它是否有任何事情要做,如果没有,它会调用“Sleep()”,这会强制再次上下文更改。因此,当“Sleep()”周期结束时,您的线程肯定不会响应,并且每个“Sleep()”周期至少强制执行 2 个其他上下文更改

阻止:

您的线程通过调用“Sleep()”将控制权交给线程 Controller ,这会强制上下文更改,但在您发出信号之前不会唤醒。这意味着每次操作仅进行一次上下文更改,并从发出信号的线程立即得到答复。

<小时/>

另外:“SetEvent()”不会阻塞,但您应该在不同的问题中询问它。

关于多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30374577/

相关文章:

performance - 寻找关于在任何其他不同设置下从这个简单的本地化性能测试中得出的结果有效性的第二意见

delphi - 使用 Delphi 的 oData 服务

python - 如何继续关闭子线程以关闭标准输入文件描述符?

c# - 如何防止套接字/端口耗尽?

c# - 多个代码块被同一个对象锁定

delphi - 如何使表单透明,同时保持组件可见?

java - 我应该使用这两种方法中的哪一种来正确停止计划线程?

python - 在 Python 中,如何在线程回调中传递参数?

delphi - 使用 Melander 的 DragDrop 套件时如何允许异常

sql-server - 如何解码 D7 中的 XML Blob 字段