【问题标题】:How to access thread variable using OmniThreadLibrary?如何使用 OmniThreadLibrary 访问线程变量?
【发布时间】:2011-06-07 06:26:00
【问题描述】:

这似乎是一件容易的事,我只是不知道从哪种方式开始使用 OmniThreadLibrary:

我创建了一个在后台进行一些处理的任务。结果存储在任务类的字段中,并不断填充新值。

现在主线程想要读取这些字段并不时显示它们的值。
因此它需要访问这些字段并确保它们在这些时刻没有被写入(同步)。

如何使用 OmniThreadLibrary 做到这一点?

【问题讨论】:

    标签: multithreading delphi omnithreadlibrary


    【解决方案1】:

    OTL 中没有直接支持所有者/线程数据共享,因为我所有的多线程经验告诉我,这样做总是一件坏事。 (同意,有时这是唯一的解决方案,但它仍然是一件坏事。)

    您应该遵循第二个 mghie 的建议 - 创建一个(可选基于接口的)对象并将该对象(或其接口)传递给线程。像这样的:

    sharedData := TSharedData.Create;
    task := CreateTask(worker).SetParameter('shared', sharedData).Run;
    

    工人:

    sharedData := Task.Param['shared'].AsObject as TSharedData;
    

    解决此问题的另一种方法是在用户按下 UpdateNow 按钮时向任务发送“请发送更新”消息。然后,该任务将使用包含当前状态的对象进行响应。但是,如果任务执行冗长的不间断计算,则此解决方案并不合适,共享状态方法效果更好。

    【讨论】:

      【解决方案2】:

      查看 OTL 测试 23,它实现了后台文件搜索。 SetParameter() 方法用于设置搜索属性,Comm 通道用于将结果传回主线程。通信已经是线程安全的,您无需再实现任何同步。

      编辑:

      如果您不想要推而是拉模型,那么您当然可以使用标准同步工具:具有临界区的对象,用于所有访问器以保护数据免受并发访问。该对象可以是任务对象本身,也可以是由 GUI 线程创建并通过(再次)调用SetParameter() 传递给任务的任何第三个对象。如果您不使用对象而是使用接口指针,您将获得更高的安全性,因为销毁的顺序不再重要,只有在重置对它实现的接口的最后一个引用时,保存数据的对象才会被销毁。

      【讨论】:

      • 据我了解这个演示,只要有新结果,任务就会将其结果发送回主线程。在我的情况下,主线程只需要在操作员按下更新按钮时获取当前值,例如仅每 1000 次创建一个新值。如果主线程仅在需要时读取值会更好。
      猜你喜欢
      • 2017-08-11
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多