简体   繁体   English

如何将boost :: bind与std :: thread结合使用(在Wt C ++中)

[英]how to use boost::bind with std::thread (in Wt c++)

I'm using Wt C++ framework and need to connect a push button with a class function. 我正在使用Wt C ++框架,需要将按钮与类函数连接。 The below code works fine but it's needed to run the function doors_open_all on a thread to allow usage of other actions at the same time. 下面的代码可以正常工作,但是需要在线程上运行功能doors_open_all以允许同时使用其他操作。

Wt::WPushButton *open_doors_button = new Wt::WPushButton("open all");
container_box->addWidget(open_doors_button);
open_doors_button->clicked().connect(boost::bind(&Servicemode::doors_open_all, this));

Something along the lines is needed: 需要遵循以下原则:

open_doors_button->clicked().connect(boost::threaded_bind(&Servicemode::doors_open_all, this));

If I understand question corrently you need to run doors_open_all function in a new thread. 如果我正确理解问题,则需要在新线程中运行doors_open_all函数。

boost::thread constructor is internaly using boost::bind You don't need to be explicit. boost::thread构造函数是内部使用boost::bind您无需明确。

So open_doors_button->clicked().connect(boost:: thread(&Servicemode::doors_open_all, this)); 所以open_doors_button->clicked().connect(boost:: thread(&Servicemode::doors_open_all, this)); should do the job. 应该做的工作。

Version with boost::thread and boost::bind : open_doors_button->clicked().connect(boost::thread(boost::bind(&Servicemode::doors_open_all, this))); 带有boost::threadboost::bindopen_doors_button->clicked().connect(boost::thread(boost::bind(&Servicemode::doors_open_all, this)));

Edit: You can also try using std::async for this purpouse too. 编辑:您也可以为此目的使用std::async

What does Servicemode::doors_open_all() do? Servicemode::doors_open_all()什么作用?

If I assume that what is taking a long time is just all backend stuff, so no widgets are being created, deleted or modified, then you can spawn a thread inside Servicemode::doors_open_all() to do all of that backend stuff. 如果我假设花费很长时间只是所有后端的东西,那么就没有创建,删除或修改任何小部件,那么您可以在Servicemode::doors_open_all()内部产生一个线程来执行所有这些后端的东西。 When it's done you have two possibilities: 完成后,您有两种可能性:

  1. Use WServer::post() , passing it the session id of your WApplication and a function, to notify the application that it should update its UI, and do all of your creating, deleting and modifying of widgets in that callback. 使用WServer::post() ,向其传递WApplication的会话ID和一个函数,以通知应用程序它应该更新其UI,并执行该回调中所有小部件的创建,删除和修改。
  2. Grab the update lock of the WApplication : 抓住WApplication的更新锁:

     // Assuming that app is a Wt::WApplication* Wt::WApplication::UpdateLock lock(app); // lock is released when it goes out of scope 

    When you have the update lock, you can go ahead and modify the widget tree. 拥有更新锁后,您可以继续修改窗口小部件树。

In any case, when doing this, you have to also do these two things: 无论如何,在执行此操作时,您还必须执行以下两项操作:

  1. Enable server push beforehand by calling app->enableUpdates(true) . 通过调用app->enableUpdates(true)预先启用服务器推送。 When the thread is done you can again disable server push with app->enableUpdates(false) . 线程完成后,您可以再次使用app->enableUpdates(false)禁用服务器推送。
  2. When you have modified the widget tree, notify Wt that it should push these changes to the client with app->triggerUpdate() . 修改小部件树后,通知Wt它应使用app->triggerUpdate()将这些更改推送到客户端。

If what takes a long time is UI-related, then there's not much you can do, since Wt assumes that you only modify a WApplication and its widgets from a single thread at a time, ie when you have the update lock. 如果花费很长时间与UI相关,那么您将无能为力,因为Wt假设您一次只能从一个线程(即,当您拥有更新锁时)修改WApplication及其窗口小部件。 The update lock is always grabbed automatically when handling an event coming from the client, like WPushButton::clicked() . 处理来自客户端的事件(例如WPushButton::clicked()时,总是会自动抓住更新锁。

Server push is demonstrated in the serverpush example. 服务器推送演示了serverpush例子。 You can find that under examples/feature/serverpush in the Wt source tree. 您可以在Wt源代码树的examples/feature/serverpush下找到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM