0

我使用 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 );

这里有什么问题?它怎么可能破坏在另一个地方访问的内存?

4

0 回答 0