我使用Boost线程。我有以下生产者 - 消费者设置:
ClassX
(在主线程中运行)创建一些数据,它传递给ClassY
(在自己的线程中运行)调用此方法:
void ClassY::PushFrame(uint8_t *data) {
try {
boost::lock_guard<boost::mutex> lk(_myMutex);
_frames.push(data);
_data_cond.notify_one();
} catch (...) {
}
}
现在,在ClassY
中,在operator()()
的正文中,有一个循环从_frames
队列中弹出数据并对其进行处理:
while (true)
{
boost::unique_lock<boost::mutex> lk(_myMutex);
// we need a loop here as wait() may return spuriously
while (_frames.empty()) {
// wait() will release the mutex and suspend the thread
_data_cond.wait(lk);
}
///wait was interrupted by notifcation of incoming new frame:
uint8_t *frame = _frames.front();
//...........the rest of code.....
}
_data_cond.wait(lk)
上会出现分段错误,或者至少这是我认为的,因为我无法在发布模式下正确调试它,因此我使用printf()
来查看它发生的位置。它总是只在循环开始时发生。它也仅在发布版本中发生,并在随机运行时抛出。 Ubuntu GCC 64位。
更新
经过一些检查之后,看起来seg错误的原因似乎不是提升线程,而是我在Linux上创建OpenGL上下文的方式。我无法找到创建它的方法。但是在使用{{3}时相反,一切都很好。
我就是这样做的:
int visual_attribs[] = {
GLX_RENDER_TYPE,
GLX_RGBA_BIT,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
None
};
int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, vmaj,
GLX_CONTEXT_MINOR_VERSION_ARB, vmin,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB | GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
None
};
_xdisplay = XOpenDisplay(NULL);
int fbcount = 0;
_fbconfig = NULL;
GLXPbuffer pbuf;
// _render_context
if (!_xdisplay) {
throw ;
}
/* get framebuffer configs, any is usable (might want to add proper attribs) */
if (!(_fbconfig = glXChooseFBConfig(_xdisplay, DefaultScreen(_xdisplay), visual_attribs, &fbcount))) {
throw;
}
/* get the required extensions */
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
glXMakeContextCurrentARB = (glXMakeContextCurrentARBProc) glXGetProcAddressARB((const GLubyte *) "glXMakeContextCurrent");
if (!(glXCreateContextAttribsARB && glXMakeContextCurrentARB)) {
XFree(_fbconfig);
throw;
}
/* create a context using glXCreateContextAttribsARB */
if (!(_render_context = glXCreateContextAttribsARB(_xdisplay, _fbconfig[0], 0, True, context_attribs))) {
XFree(_fbconfig);
throw;
}
/* create temporary pbuffer */
int pbuffer_attribs[] = {
GLX_PBUFFER_WIDTH, 32,
GLX_PBUFFER_HEIGHT, 32,
None
};
pbuf = glXCreatePbuffer(_xdisplay, _fbconfig[0], pbuffer_attribs);
XFree(_fbconfig);
XSync(_xdisplay, False);
/* try to make it the current context */
if (!glXMakeContextCurrent(_xdisplay, pbuf, pbuf, _render_context)) {
/* some drivers does not support context without default framebuffer, so fallback on
* using the default window.
*/
if (!glXMakeContextCurrent(_xdisplay, DefaultRootWindow(_xdisplay),
DefaultRootWindow(_xdisplay), _render_context)) {
throw;
}
}
退出时,析构函数会进行清理:
glXMakeCurrent( _xdisplay, 0, 0 );
glXDestroyContext( _xdisplay, _render_context );
XCloseDisplay( _xdisplay );
这里有什么问题?怎么可能破坏在其他地方访问的内存?