c++ - Boost::thread 如何在主线程和工作线程之间同步?

标签 c++ multithreading boost boost-thread

我正在尝试实现多线程设计,需要一些有关线程同步的帮助。

我有两个类,A 类和 B 类。我将使用伪代码进行解释 A 类在主函数中创建。

class A
{
   public:
   A();
   ~A();

   void tick();
   void addEntity();
   private:
   std::list<entity> entityList;
   B* _b;
};

B类如下:

 class B
{
   public:
   B();
   ~B();

   void createSimulation();
   void startSimulation();
   void registerCallbacks(SimEngine& sim);
   void entityCreatedCallback();

   boost::signal<void()> signalEntityCreated;

   private:
   simEngine* sim;


};

A 类实现有点像这样:

A::A()
{
    _b = new B();
    _b->signalEntityCreated.connect(boost::bind(&A::AddEntity, this));
    _b->createSimulation();
}

A::~A()
{

}

void A::tick()
{
    entity ent = entityList.pop_front();
    //process the entity
}


void A::addEntity(entity ent)
{
     entityList.push_back(entity);
}

B 类实现有点像这样:

B::B()
{
}

B::~B()
{
}

 B::registerCallback(SimEngine& sim)
 {
     sim.connect("ENTITY_CREATED", entityCreatedCallback);
 }

 void B::createSimulation()
 {
     boost::thread sim_thread(boost::bind(&B::startSimulation, this));
 }


 void B::startSimulation()
 {
      sim =  new SimEngine();
      registerCallback(sim);

      sim->start();

 }

 void B::entityCreatedCallback(simEngine& sim)
{
    signalEntityCreated(sim.lastEntity);
}

所以,主要思想是 A 类创建 B 类,然后 B 类启动一个模拟线程。在开始模拟之前,它会在模拟中注册一些回调函数。当模拟中的某些状态发生变化(即创建的实体)时,将调用这些回调函数。

A类使用boost信号槽机制将B类中的信号(signalEntityCreated)与A类中的本地成员函数连接起来。 在 B 类中,回调调用信号以触发 A 类中的成员函数调用。在本例中为 addEntity,它正在向 std::list 添加新条目。

A类有一个tick函数,在每一帧都进行tick,需要处理addEntity函数添加的任何实体。

现在,我需要正确地同步这个生产和消费实体机制。类 A 在主线程中运行并且绑定(bind)到渲染线程,因此它不能等待互斥量(长时间),否则渲染性能会降低。

我的观察, 当仿真在不同的线程中运行时,所有回调都属于该线程。当使用 boost::signal 调用成员函数时,该成员函数也在模拟线程中运行。但是,处理(在 tick 内)需要在主线程中运行。

有什么建议吗?

最佳答案

您只想创建一个从渲染事件循环中轮询的消息队列。

此外,您可以按照事件对象模式¹ 对模拟和/或渲染器 (A) 进行建模。

请注意,当跨线程边界传递事件消息时,您也需要传递实体,否则会出现竞争条件(在处理事件之前创建了多个实体)。


¹ 参见例如 - https://en.wikipedia.org/wiki/Active_object - http://www.drdobbs.com/parallel/prefer-using-active-objects-instead-of-n/225700095 - - https://rosettacode.org/wiki/Active_object#C.2B.2B实际上是一个很好的例子

关于c++ - Boost::thread 如何在主线程和工作线程之间同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47289816/

相关文章:

c++ - 默认模板参数中的 lambda 是否被视为直接上下文的一部分?

c++ - 模板中的可选变量声明

c# - 我是否需要使用 try catch 或检查 ThreadPool.QueueUserWorkItem 的返回值

c++ - 使用默认参数 boost list_of

c++ - 在没有桌面环境 C++ 的情况下绘制图形?

c++ - 从重载的下标运算符调用虚函数

java - StreamCorruptedException : invalid type code: AC

c - 在 C 中使用信号量进行多线程

c++ - 如何找到 BGL 图中两个顶点之间的最短路径?

c++ - 使用python boost 编译错误