使用类对象增强线程工人 我是C++并发的新手。我开始使用Boost线程作为那些跨平台的解决方案。到目前为止,我看到的大多数例子都是通过将单独的函数传递到线程中来处理的。例如,在我的例子中,我有一个类,它有两个类的实例,在我的例子中是OpenGL上下文和与渲染相关的东西。 我了解到,将对象指定给线程是通过以下方式完成的: mythread=new boost::thread(boost::ref(*this));

使用类对象增强线程工人 我是C++并发的新手。我开始使用Boost线程作为那些跨平台的解决方案。到目前为止,我看到的大多数例子都是通过将单独的函数传递到线程中来处理的。例如,在我的例子中,我有一个类,它有两个类的实例,在我的例子中是OpenGL上下文和与渲染相关的东西。 我了解到,将对象指定给线程是通过以下方式完成的: mythread=new boost::thread(boost::ref(*this));,c++,multithreading,concurrency,C++,Multithreading,Concurrency,其中*这是指向调用它的实例的指针。 但是对于这个类实例中的其他复合类呢?我应该对它们中的每一个都执行相同的操作吗?或者,一旦我在宿主类上调用它们,它们就会被自动线程化吗? 我最初的问题是在线程中概述的。因此,一旦我启动线程,它看起来就像OpenGL上下文保留在主线程中一样(请参阅底部的GPUThread类) 这是我的线程类: GPUThread::GPUThread(void) { _thread =NULL; _mustStop=false; _fr

其中*这是指向调用它的实例的指针。 但是对于这个类实例中的其他复合类呢?我应该对它们中的每一个都执行相同的操作吗?或者,一旦我在宿主类上调用它们,它们就会被自动线程化吗? 我最初的问题是在线程中概述的。因此,一旦我启动线程,它看起来就像OpenGL上下文保留在主线程中一样(请参阅底部的GPUThread类)

这是我的线程类:

  GPUThread::GPUThread(void)
  {
      _thread =NULL;
      _mustStop=false;
      _frame=0;


      _rc =glMultiContext::getInstance().createRenderingContext(GPU1);
      assert(_rc);

      glfwTerminate(); //terminate the initial window and context
      if(!glMultiContext::getInstance().makeCurrent(_rc)){

      printf("failed to make current!!!");
      }
         // init engine here (GLEW was already initiated)
      engine = new Engine(800,600,1);

   }
   void GPUThread::Start(){



      printf("threaded view setup ok");

       ///init thread here :
       _thread=new boost::thread(boost::ref(*this));
      _thread->join();

  }
 void GPUThread::Stop(){
   // Signal the thread to stop (thread-safe)
    _mustStopMutex.lock();
    _mustStop=true;
    _mustStopMutex.unlock();

    // Wait for the thread to finish.
    if (_thread!=NULL) _thread->join();

 }
// Thread function
 void GPUThread::operator () ()
{
       bool mustStop;

      do
     {
        // Display the next animation frame
        DisplayNextFrame();
        _mustStopMutex.lock();
        mustStop=_mustStop;
       _mustStopMutex.unlock();
    }   while (mustStop==false);

}


void GPUThread::DisplayNextFrame()
{

     engine->Render(); //renders frame
     if(_frame == 101){
         _mustStop=true;
     }
}

GPUThread::~GPUThread(void)
{
     delete _view;
     if(_rc != 0)
     {
         glMultiContext::getInstance().deleteRenderingContext(_rc);
         _rc = 0;
     }
    if(_thread!=NULL)delete _thread;
 }
当该类运行OpenGL上下文时会发出错误。我无法从缓冲区读取像素数据。我想这是因为我在调用该类之前初始化了rc(渲染上下文)并设置了当前上下文:

 _thread=new boost::thread(boost::ref(*this));
我试着在线程初始化之后执行它,但是它直接跳转到线程函数中,使对象没有初始化。
那么,在一个包含所有内容的类上设置boost线程的正确方法是什么呢?

简短回答:您需要将OpenGL调用
glMultiContext::getInstance().makeCurrent(_rc)
以及
new Engine()
调用从
GPUThread
构造函数移动到
GPUThread::operator()()

更详细的回答:OpenGL上下文似乎以某种方式绑定到特定线程,如图所示。在要将上下文绑定到的线程中运行时,需要调用
makeCurrent()
。当前运行的线程是
makeCurrent()
的一个(完全隐式)参数

您从主线程调用
GPUThread
构造函数,然后从主线程调用
GPUThread::Start()
。在子线程上实际运行的第一个位置是
GPUThread::operator()()
函数的顶部。这就是必须调用
glMultiContext::getInstance().makeCurrent(_rc)
的地方(在调用
engine->Render()之前)


我不理解OpenGL的
makeCurrent()
的设计原理。我最好的猜测是,他们一定在OpenGL上下文的实现中使用了某种线程本地存储,或者其他什么。“正常”2D Windows设备上下文也有限制,它绑定到一个线程,这就是我猜想OpenGL可能有类似的限制。

C++ 11提供了一个跨平台的线程解决方案。我不能移动到C++ 11,因为我有一些旧的LIBS。功能。主线程可能正在调用GPUThread::Start(),然后阻塞调用
\u thread->join()
。所以你只运行过一个线程?等等。。。当你谈到OpenGL“渲染上下文”时,是不是Windows上的某些东西可能会创建某种依赖于当前操作系统线程的上下文?这个站点:帮助吗?特别是第一个问题似乎暗示,当您在一个线程上创建opengl上下文时,您需要执行一些额外的api调用来将该上下文与任何其他线程关联起来。想必他们(OpenGL实现者)正在进行某种线程本地存储黑客攻击,把你搞砸了?