我使用 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 位。
更新:
经过更多检查后,似乎段错误的原因不是提升线程,而是我在 Linux 上创建 OpenGL 上下文的方式。我找不到创建它的方式有什么问题。但是当使用GLFW来代替它时,一切正常伟大的。
我就是这样做的:
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 );
这里有什么问题?它怎么可能破坏在另一个地方访问的内存?