【问题标题】:c++ boost::thread execute code on main thread?c++ boost::thread 在主线程上执行代码?
【发布时间】:2011-05-20 11:43:40
【问题描述】:

是否有可能在调用 boost::thread 运行一些指令后回到主线程?

我的代码基于前摄器模式,但是某个函数可能需要一些时间,所以为了不阻塞整个程序,我正在创建一个运行该函数的线程。 当这个函数结束时,我需要调用另一个函数,但它必须在主线程上运行。 我有一个连接池,它不是线程安全的,我真的很想避免互斥锁。

有没有稳定的方法在主线程上运行函数(在另一个线程上调用)?

就像在 ObjectiveC 中一样 performSelectorOnMaintThread

【问题讨论】:

  • 您正在寻找消息队列。
  • 当然,如果你在主线程上休眠,你就阻塞了主线程。你还能期待什么?睡眠不能像宣传的那样工作?
  • (另外,对不起,我的意思是message pump)。
  • 我想我还不熟悉消息队列...忘记最后一个问题。我将在消息队列中通知自己...

标签: c++ boost-thread


【解决方案1】:

如果你想让一个函数在主线程中运行,你将不得不实现某种类型的消息传递系统。因此,例如,您将启动主线程,然后启动工作线程。工作线程将完成它的工作,而主线程将等待来自工作线程的一些返回值(即主线程将检查消息队列或类似性质的东西)。当工作线程完成时,它将向主线程的消息队列传递一个结构(即消息),其中包含指向它希望主线程运行的函数的指针。你的信息可以很简单:

struct message
{
    typedef void (*func_ptr)(void); //or whatever your function signature would be

    func_ptr function;
    bool finished;

    message(): function(NULL), finished(false) {}
};

所以当工作线程完成后,它会创建一条新消息,初始化消息中的函数指针,然后将该消息推回主线程正在等待的队列中。然后主线程从队列中读取消息,并调用函数。

顺便说一句,让主线程“等待”而不必将其保持在循环中并耗尽 CPU 周期的有效方法是在主线程和主线程之间使用信号量或条件变量(如boost::condition)工人。

还有一点要注意...“消息队列”只是一个std::queue<message>,具有主线程读取和工作线程写入的适当锁定访问权限。主线程写入的工作线程也可以有另一个消息队列,如果您需要线程之间的双向通信,工作线程会读取。

【讨论】:

    【解决方案2】:

    我想你可能想看看boost asio strands。它们会让你指定要在哪个线程(链)上做一些工作,它会自动在那个链上排队。

    请注意,股线实际上更像是一根纤维(意思是:如果股线多于实际线,股线将被多路复用到可用线程上)。

    IIRC 这不会但是让您有机会明确指定主线程1。然而,这往往不是实际要求:strand 让您轻松做到的是确保 strand 中的操作在同一个 逻辑线程 上运行,即不可能有并发 在一条链中。

    琐事:Boost Asio io_service.run() 是消息泵的一个例子

    这是 Boost Asio 的示例页面:http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html

    【讨论】:

    • strands 看起来很有前途。但是,如果我理解正确,我应该让我的 ConnectionPool 可运行,并让它等到它被请求(例如获取连接),我应该如何让它等待,一个带有互斥锁的 cond_wait ?
    • 我对你的连接池一无所知。添加了指向 Boost Asio 示例的链接
    【解决方案3】:

    在多线程应用程序中(至少对我而言),主线程并没有做太多事情,并且所有内容都抵消了在启动时创建的其他线程。主线程仅阻塞/等待(条件变量),直到指示我们可以退出。所有工作都在线程之间翻转/翻转,这使事情变得更加容易。

    正如上面建议的那样,最好的方法是拥有消息队列(每个队列都包装一个工作线程或池),您可以将消息发布到一个或另一个。使用回调和其他消息传递机制,您可以让“主”线程向工作线程发送消息以完成工作,并在完成结果后提供回调以将消息发回“主”线程。在此期间,“主”线程可以继续处理其他消息和操作,同时等待结果,如果它有任何其他工作要做。

    【讨论】:

      【解决方案4】:

      如果您在 Visual Studio 2010 中运行,它应该始终在调试中工作。但是,由于存在错误,您可能需要禁用然后重新启用“优化”才能使发布工作。

      【讨论】:

        【解决方案5】:

        我也遇到过类似的情况。带有 boost 线程的 mfc 对话框。为了解决这个问题,我在 boost 线程中添加了信号 2,并将它们绑定到对话框上的成员函数。当信号进入对话框成员函数时,我检查了线程 ID。如果线程 id 与对话线程 id 不同,我将 boost 函数推送到函数的 std::queue 上(相同的签名)。 onidle, kickidle 我检查队列并执行函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-02
          • 2015-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-27
          • 1970-01-01
          相关资源
          最近更新 更多