2011-05-20 91 views
10

在调用运行一些指令的boost :: thread之后,是否有可能返回主线程?C++ boost ::线程在主线程上执行代码?

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

是否有稳定的方式来运行主线程上的函数(调用另一个线程)?

就像在的ObjectiveC performSelectorOnMaintThread

+0

你正在寻找一个消息队列。 – 2011-05-20 11:48:09

+0

当然,如果你睡在主线程上,你会阻塞主线程。你还会期待什么?睡觉不能像广告一样工作? – 2011-05-20 11:58:33

+0

(另外,抱歉,我的意思是[消息泵(http://en.wikipedia.org/wiki/Event_loop))。 – 2011-05-20 11:59:56

回答

2

我想你可能想看看boost asio strands。他们会让你指定哪个线程(线程)做一些炒锅,它会自动排队。

请注意,一根线实际上更像是一根纤维(意思是说,如果有比实际线更多的线,那么线将被复用到可用线上)。

IIRC此不会但是给你机会明确指定主线程1。然而,这通常不是实际的要求:什么股让你容易做的是确保在一个股中的操作运行在相同的逻辑线程上,即在并行内没有并发是永远不可能的

琐事:升压短耳io_service.run()是泵

下面是升压短耳样品页面的消息的示例:http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html

+0

股很有希望。但是,如果我理解正确的话,我应该让我的连接池的Runnable,并使其等待,直到它被征求(例如获取连接),我应该怎样让它等待,与互斥体cond_wait? – TheSquad 2011-05-20 12:45:40

+0

我对连接池一无所知。添加到Boost Asio Samples的链接 – sehe 2011-05-20 12:56:20

0

在多线程应用程序(至少对于我)主线程没有太多的工作,一切都抵消了在启动时创建的其他线程。主线程只会阻止/等待(条件变量),直到指示我们很好退出。所有工作都在线程之间翻转/翻转,这使事情变得更容易。

而且如上所示,最好的方法是拥有消息队列(每个队列包装一个工作线程或池),并且可以将消息发布到另一个或另一个消息队列中。使用回调函数和其他消息机制,可以让“主”线程向工作线程发送消息来完成工作,并提供回调以在完成结果时将消息发送回“主”线程。在此期间,如果有其他工作要做,“主”线程可以在等待结果的同时继续处理其他消息和操作。

5

如果你想要一个函数在主线程中运行,你将不得不实现某种类型的消息传递系统。因此,例如,您将启动您的主线程,然后启动工作线程。工作线程可以完成工作,而主线程将等待工作线程的返回值(即主线程将检查消息队列或其他特性)。当工作线程完成时,它将通过指向它想让主线程运行的函数的指针传递给主线程的消息队列的结构(即消息)。您的邮件可以很简单:

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>用适当的锁定访问主线程读取,并辅助线程写入。对于主线程写入的工作线程,也可以有另一个消息队列,如果需要线程之间的双向通信,则工作线程将读取。

0

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

0

我也有类似的情况。带升压线程的mfc对话框。解决我添加signals2到boost线程并将它们绑定到对话框上的成员函数。当信号进入对话成员函数时,我检查了线程ID。如果线程ID不同于对话线程ID,我会将一个boost函数推送到函数的std :: queue(相同签名)上。 onidle,kickidle我检查队列并执行这些功能。

相关问题