用类对象提升线程工作器
Boost threads workers with class objects
我是c++并发新手。我开始使用boost线程作为跨平台解决方案。到目前为止,我看到的大多数示例都处理将单独的函数传递到线程中的问题。比如这个。在我的例子中,我有一个类它有更多类的实例,在我的例子中是OpenGL context和渲染相关的东西。我已经了解到,将对象分配给线程是这样完成的:
mythread=new boost::thread(boost::ref(*this));
其中*this是指向调用它的实例的指针。但是在这个类实例中是复合的其他类呢?我是否应该为它们中的每一个做同样的事情,或者它们是自动线程化的,一旦我在宿主类上调用它?我原来的问题概述在这个线程。一旦我启动线程它看起来OpenGL context仍然在主线程中。(参见底部的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上下文发出错误。我不能从缓冲区读取像素数据。我想这是因为我init _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++为线程工作动态地分割例程
- 自 Windows 10 20H1 以来,具有单独线程的多个窗口停止工作
- 餐饮哲学家问题 - 只有 2 个线程工作
- 工作线程在执行太快后永久休眠
- 唤醒多个线程以在每个条件下工作一次
- Qt::D irectConnection在多线程环境中使用时如何工作?
- ZeroMQ 在使用 std::thread 创建工作线程时崩溃
- 工作线程一直在等待,condition_variable甚至调用了notify_all
- 使用 std::atomic 标志和 std::condition_variable 在工作线程上等待
- SIGABRT 和线程相关的异常,但在调试期间工作正常
- c++线程的安全性和时间效率:为什么有互斥检查的线程有时比没有它的线程工作得更快
- 在多线程工作负载上解释Gperftools的结果
- 我的线程工作不好,它给出了所有结果,最后没有一个接一个,GUI 在线程运行期间挂起?
- BOOST::线程工作线程同步,C++和OpenCV
- 线程工作不正常
- 提升线程工作线程对象在线程完成后的重用
- 线程问题,其中一个线程工作,但导致调用方法不返回
- 线程工作目录
- MFC主UI线程工作和模态对话框
- 用类对象提升线程工作器