是否可以在后台线程上创建一个对象,而主线程上没有引用

本文关键字:线程 引用 创建 后台 是否 一个对象 | 更新日期: 2023-09-27 17:56:43

股票交易应用程序使用一个类库来获取股票报价更新的回调,另一个类库来获取订单执行或取消的回调。我目前在线程池中执行回调。我为每个回调启动一个后台线程。线程的生存期非常短,所涉及的工作包括获取数据和通知观察者。一旦通知观察者,后台线程就会死亡。当我的策略订阅了超过 1000 个活跃交易品种时,我会收到内存不足异常。

如何改进此设计?我正在考虑在开始时启动两个线程,一个用于引号,另一个用于执行,并在各自的线程上创建每个对象。然后只需有一个共享对象,它允许在线程中添加和删除观察者。但是 1) 您将如何保持线程活动以接收回调?2)你怎么能有一个在线程上初始化的回调对象,而在主线程上没有引用?这可能吗?

任何帮助将不胜感激。

是否可以在后台线程上创建一个对象,而主线程上没有引用

使用具有简单队列的生产者/使用者模型。然后,您有一定数量的工作线程正在运行,并且不会遇到此问题。

至于如何调用回调函数,你可以使用这样的结构:

struct WorkerData
{
    Data data;
    Delegate someCallback;
}

当工作线程完成数据处理后,它可以调用回调本身。

您描述的是应用程序的总体情况。 为了重新设计您的应用程序,我们提出了具体要求,并且至少是参与者如何相互交互的简化模型。 您的非正式描述不够精确,无法建议特定的数据结构和算法,因为如果不了解所有足够的详细信息,我们可能会省略一些关键内容,无法满足您的需求。

说了所有正确的词,你有一个特定的问题,内存不足,你需要解决一些问题。 回到原型设计。 写一个非常小但残酷的程序来演示你想做什么。 然后将其纵向扩展到应用程序。 在原型尺寸下进行设计要容易得多。

编辑:

由于内存不足,因此最可能的原因是内存泄漏,或者您只是一个近乎实时的系统,其容量不足以处理您遇到的负载。 泄漏可能是由于通常的嫌疑人造成的,例如,没有分离可以使用内存分析器诊断的事件处理程序,但我们现在将排除这一点。

如果你必须在报价更新时跟上报价,它们必须去某个地方,比如队列或被调度到线程,除非你能跟上,否则这可能会无限增长。

解决此问题的唯一方法是:

  • 在地板上扔一些报价
  • 获得更强大的硬件
  • 更高效地处理报价

我认为您希望有一个明确的替代方案,可以使用新的数据结构或算法更有效地处理报价,这可能会产生很大的不同。 但是,即使您确实提高了效率,问题仍然可能再次出现,并且您可能被迫考虑在过载条件下优雅地降级,而不是因内存不足而失败。

但一般来说,对于高性能,越简单越好,线程交换越少越好。 例如,如果在更新中完成的工作很小,则使其同步可能是一个巨大的胜利,即使它看起来违反直觉。 您必须知道更新处理程序的作用,最重要的是对于近实时系统,您必须测量,测量,测量才能凭经验知道哪个最快。

对我来说

我目前在线程池中执行回调

一旦通知观察者,后台线程就会死亡

有轻微的矛盾。我怀疑您可能打算使用池中的线程,但每次都不小心使用新的"免费"(未池化)线程。

您可能需要查看 WeakReference 的文档。

但是,我建议您首先使用探查器/perfmon来查找资源泄漏。用排队方法替换整个 shebang 听起来很合理,但它非常接近您拥有适当线程池的 shebang。