gpt4 book ai didi

linux - Go 导致 OpenGL 与 time.Tick 但不是 time.After 发生段错误

转载 作者:数据小太阳 更新时间:2023-10-29 03:07:32 28 4
gpt4 key购买 nike

我有以下两个文件:

bridge.go:

package cube

// #cgo LDFLAGS: -lGL -lGLEW -lglfw
// #include <GLFW/glfw3.h>
// int init(GLFWwindow**);
// void render(GLFWwindow*);
import "C"

import (
"fmt"
"time"
)

func Init() {
var window *_Ctype_GLFWwindow
windowWat := (*[0]byte)(window)
fmt.Printf("Calling init\n")
if C.init(&windowWat) != 1 {
return
}
window = (*_Ctype_GLFWwindow)(windowWat)

//t := time.Tick(time.Second) // Doesn't work
t := time.After(time.Second) // Works

<-t
fmt.Println("Rendering")
C.render((*[0]byte)(window))

select {}
}

立方体.c:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

#define INIT_WINDOW_W (800)
#define INIT_WINDOW_H (800)

void render(GLFWwindow* window) {
glClearColor(135.0f / 255.0f, 206.0f / 255.0f, 250.f / 254.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwSwapBuffers(window);
}

static void glfw_error(int errno, const char* description) {
fprintf(stderr, "GLFW [%d] %s\n", errno, description);
exit(1);
}

int init(GLFWwindow** window) {
GLenum glewErr;

glfwSetErrorCallback(glfw_error);
if (!glfwInit()) {
return 0;
}

*window = glfwCreateWindow(
INIT_WINDOW_H,
INIT_WINDOW_W,
"wat",
NULL,
NULL
);
if (*window == NULL) {
glfwTerminate();
return 0;
}

glfwMakeContextCurrent(*window);

glewErr = glewInit();
if (glewErr != GLEW_OK) {
fprintf(stderr, "glewInit failed: %s\n", glewGetErrorString(glewErr));
return 0;
}

if (!GL_VERSION_2_0) {
fprintf(stderr, "Don't have OpenGL >= 2.0\n");
return 0;
}

return 1;
}

以及调用 cube.Init() 的 main.go 文件,仅此而已。

我的问题出在调用 C.render 之前的行中。如果我执行 time.After,它会正常工作并按预期显示蓝色窗口。如果我执行 time.Tick,它很少还会显示那个蓝色窗口,而是显示黑色窗口或段错误。这个测试用例是从我的实际代码中大大提炼出来的。

我有一种感觉,go 的调度程序以某种方式搞砸了,但我想不出如何(或如何测试/修复它)。我很好奇是否有人知道造成这种情况的原因,或者可以想出任何进一步调查的方法。

其他可能重要的信息:

  • Arch Linux,3.14.4-1-ARCH.x86_64
  • GLFW 3.0.4-1
  • GLEW 1.10.0-2
  • nVidia GeForce GTX 570M
  • nVidia 驱动程序 337.12-1
  • go1.2 linux/amd64

编辑:

这是段错误消息:

SIGSEGV: segmentation violation
PC=0x7fda7d6a2e29
signal arrived during cgo execution

runtime.cgocall(0x401260, 0x7fda7d6f0e58)
/opt/go/src/pkg/runtime/cgocall.c:149 +0x11b fp=0x7fda7d6f0e40
game/cube._Cfunc_render(0x24e13b0)
game/cube/_obj/_cgo_defun.c:62 +0x31 fp=0x7fda7d6f0e58
game/cube.Init()
/tmp/wat/cube/bridge.go:28 +0x156 fp=0x7fda7d6f0ee0
main.main()
/tmp/wat/main.go:10 +0xac fp=0x7fda7d6f0f48
runtime.main()
/opt/go/src/pkg/runtime/proc.c:220 +0x11f fp=0x7fda7d6f0fa0
runtime.goexit()
/opt/go/src/pkg/runtime/proc.c:1394 fp=0x7fda7d6f0fa8

goroutine 3 [syscall]:
runtime.goexit()
/opt/go/src/pkg/runtime/proc.c:1394

rax 0x0
rbx 0x24e13b0
rcx 0x7fda7d6f0e58
rdx 0x7fda7d6f0df0
rdi 0x24e13b0
rsi 0xc210001900
rbp 0xc21002a000
rsp 0x7fda76506dc8
r8 0xc210001120
r9 0x7fda7d6f0df0
r10 0x7fda76506ba0
r11 0x7fda7d6a2e20
r12 0x0
r13 0x7fda76507700
r14 0x0
r15 0x7fda76d07c80
rip 0x7fda7d6a2e29
rflags 0x10202
cs 0x33
fs 0x0
gs 0x0
exit status 2

它似乎在调用 glClearColor

时出现段错误

最佳答案

将我的评论变成答案:

出于某种原因,OpenGL 通常要求所有内容都在同一个操作系统线程中运行。 time.Tick 和 time.After 调用不同的运行时函数,一个可能导致不同的 opengl 调用在不同的线程中运行。默认情况下,Go make 不保证 goroutine 在特定线程上运行。

要解决此问题,您需要使用 runtime.LockOSThread .这将确保 goroutine 并且只有那个 goroutine 在当前线程上运行。

您可以在此处阅读有关该主题的更多信息:https://groups.google.com/forum/#!topic/golang-nuts/5Pvv1Gr1eoo

关于linux - Go 导致 OpenGL 与 time.Tick 但不是 time.After 发生段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23862499/

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