gpt4 book ai didi

linux - 在 linux 下使用带有 pthreads 的 glGetString() 的段错误

转载 作者:IT王子 更新时间:2023-10-29 00:58:05 24 4
gpt4 key购买 nike

我正在尝试在后台线程中加载纹理以帮助加快我的应用程序。

我们使用的堆栈是 Linux 上的 C/C++,使用 gcc 编译。我们正在使用 OpenGL、GLUT 和 GLEW。我们一直在使用 libSOIL 进行纹理加载。

最终,使用 libSOIL 启动纹理加载失败,因为它遇到导致段错误的 glGetString() 调用。为了缩小问题范围,我编写了一个非常简单的 OpenGL 应用程序来重现该行为。下面的代码示例不应该“做任何事情”,但也不应该出现段错误。如果我知道为什么会这样,理论上我可以修改 libSOIL,使其在 pthreaded 环境中运行。

void *glPthreadTest( void* arg ) {

glGetString( GL_EXTENSIONS ); //SIGSEGV
return NULL;

}

int main( int argc, char **argv ) {

glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );

glewInit();

glGetString( GL_EXTENSIONS ); // Does not cause SIGSEGV

pthread_t id;
if (pthread_create( &id, NULL, glPthreadTest, (void*)NULL ) != 0)
fprintf( stderr, "phtread_create glPthreadTest failed.\n" );

glutMainLoop();
return EXIT_SUCCESS;

}

来自 gdb 的此应用程序的示例堆栈跟踪如下所示:

#0  0x00000038492f86e9 in glGetString () from /usr/lib64/nvidia/libGL.so.1
No symbol table info available.
#1 0x0000000000404425 in glPthreadTest (arg=0x0) at sf.cpp:168
No locals.
#2 0x0000003148e07d15 in start_thread (arg=0x7ffff7b36700) at pthread_create.c:308
__res = <optimized out>
pd = 0x7ffff7b36700
now = <optimized out>
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140737349117696, -5802871742031723458, 1, 211665686528, 140737349117696, 0, 5802854601940796478,
-5829171783283899330}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
not_first_call = 0
pagesize_m1 = <optimized out>
sp = <optimized out>
freesize = <optimized out>
#3 0x00000031486f246d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:114
No locals.

您会注意到我使用的是 nvidia libGL 实现,但这也与 Ubuntu 用于英特尔高清显卡的 mesa libgl 相同。

关于可能出错的任何提示,或者如何进一步调查以了解发生了什么?

编辑:这是我的示例测试的#includes 和编译字符串:

#include <SOIL.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#include <signal.h>
#include <pthread.h>
#include <cstdio>

g++ -Wall -pedantic -I/usr/include/SOIL -O0 -ggdb -o sf sf.cpp -lSOIL -pthread -lGL -lGLU -lGLEW -lglut -lX11

最佳答案

为了使任何 OpenGL 调用正常运行,它需要一个 OpenGL 上下文。上下文是使用窗口系统绑定(bind)调用(如 wglCreateContext 或类似的)创建的。创建上下文后,需要将其“设为当前”,这意味着将上下文与当前执行线程相关联。这是通过另一个特定于窗口系统的调用完成的(例如 Microsoft Windows 的 wglMakeCurrent 或 X Windows 的 glXMakeCurrent)。 GLUT 将所有这些复杂性从您身上抽象出来,在您调用 glutCreateWindow 时执行所有这些操作。

现在,需要知道的一个重要规则是,在任何时候,一个执行线程只能有一个 OpenGL 上下文。因此,在 OP 的原始示例中,如果她/他可以在他们创建的 Pthread 中使上下文成为当前上下文,那么上下文将在主线程中丢失。保持所有这些一致的方法是只在单个线程中使用单个上下文。 (让 OpenGL 上下文共享数据是可能的,但这既不会被 GLUT 暴露,也不会在不使用窗口系统上下文创建调用的情况下实现)。

在您的情况下,GLUT 可能不允许访问您真正需要的内容(即 OpenGL 上下文),以使其在另一个线程中处于当前状态。您需要自己创建和管理 OpenGL 上下文。

关于linux - 在 linux 下使用带有 pthreads 的 glGetString() 的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15056123/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com