【问题标题】:Multiple Producers Single Consumer Queue多生产者单消费者队列
【发布时间】:2010-04-28 16:05:18
【问题描述】:

我是多线程的新手,我设计了一个程序,该程序从两个微控制器接收数据,测量不同的温度(环境温度和水温)并将数据绘制到屏幕上。现在这个程序是单线程的,它的性能很糟糕。

我获得了多线程的基本设计方法,但还不足以创建线程来执行任务,但我不知道如何让线程执行单独的任务并将数据放入共享数据池中。我想我需要创建一个包含一个消费者和多个生产者的队列(想使用 std::queue)。我在 gtkmm threading docs 上看到了一些代码,这些代码显示了一个 Con/Pro 队列,它们会锁定队列对象,生成数据并向睡眠线程发出信号,表明它已完成,然后生产者将进入睡眠状态。对于我需要的东西,我需要让一个线程休眠,如果我没有让任何线程休眠,是否会出现数据冲突,并且休眠一个线程会导致数据显着的数据延迟(我需要绘制 30 帧的实时数据)秒)

我将如何使用 gtkmm/glibmm 库对这样的队列进行编码。

【问题讨论】:

  • Linux 提供了一个命名管道,这个很有用。

标签: c++ multithreading queue gtkmm


【解决方案1】:

这里有一个建议:
1.有两个线程,负责获取数据并放入缓冲区。每个线程都有自己的(循环)缓冲区。
2. 将有第三个线程负责从缓冲区中获取数据并在屏幕上显示。
3. screen线程向数据线程发送消息请求一些数据,然后显示数据。这些消息有助于同步执行并避免死锁。
4. 任何线程都不应该“等待单个或多个对象”,而是轮询事件。

想想这个使用人的场景。一个人正在提供水温读数。另一个提供环境温度读数的人。第三人接收或请求数据并显示数据(在白板上)。目标是让每个人都以最高效率运行而不会发生任何冲突。

【讨论】:

  • 为了让 GUI 线程从每个循环缓冲区中读取,我会让工作线程为 gui 线程提供指向缓冲区中最旧数据对象位置的指针,并且工作线程将自动更新缓冲区中最旧的项目?
  • 不,“不要越过溪流。”工作线程将提供访问数据的方法。这将数据结构与 GUI 线程隔离开来,也避免了任务之间的数据共享问题。工人知道他的库存结构。让他给你你所求的;不要弄乱他的档案系统。 ;-)
  • 这无疑是实现我想要的最好的方法我只是对如何实现 gui 和 worker 之间的链接有点困惑。我看到它的方式是我在主线程中有一个硬件对象的实例。 HWobj 工作线程已启动。 HWobj 有一个名为 pop_front() 的方法,它返回并删除循环队列的最前面的项目。当 main 方法调用 pop 时,它会得到最旧的项目。如果这是正确的方法,从缓冲区读取数据时仍然会有一点锁定?
【解决方案2】:

如果您正在寻找一个无锁的实现,您将找不到。在写入数据结构时,需要采取一些措施来防止两个线程同时更新数据结构并破坏它。

你有什么理由不能让每个线程自己收集,用它自己的结构,然后在最后组合结果?

【讨论】:

  • 每个线程将与单个 uC 通信,并处理数据并将其打包以绘制到屏幕上。锁定系统是否更容易实现,不确定如何实现您描述的内容
  • @Talguy:什么是 uC?如果您的意思是微秒,并且您尝试每微秒更新一次显示,那么再多的多线程也无济于事。显示器更新不那么快;你最好在那种情况下使用轮询。
  • uC = 微控制器。很抱歉造成混乱
  • @Talguy:没问题(缩写在 cmets 中完全可以接受,因为它们有长度限制)如果是这种情况,我仍然会推荐轮询解决方案。 IE。显示器每隔一段时间就会自我更新一次(例如,对于大多数用途来说,每 50-100 毫秒一次就足够了)。那么工作线程之间不需要有一组公共数据,UI 只需要对这些线程进行读取访问。
  • 我明白你的意思。我将使用 Thomas Matthews 建议的专用循环缓冲区
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多