C ++ 11< thread>使用OpenGL进行多线程渲染可防止主线程读取stdin [英] C++11 <thread> multithreads rendering with OpenGL prevents main thread reads stdin

查看:127
本文介绍了C ++ 11< thread>使用OpenGL进行多线程渲染可防止主线程读取stdin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎与平台相关(笔记本电脑上可与Ubuntu 12.04一起使用,而工作站上的另一Ubuntu 12.04不可用).

It seems to be platform related (works with Ubuntu 12.04 on my laptop, doesn't work with another Ubuntu 12.04 on my workstation).

这是有关我在两个线程中执行的操作的示例代码.

This is a sample code about what I am doing with two threads.

#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
#include <GL/glfw.h>

using namespace std;

int main() {
  atomic_bool g_run(true);
  string s;
  thread t([&]() {
    cout << "init" << endl;

    if (!glfwInit()) {
      cerr << "Failed to initialize GLFW." << endl;
      abort();
    }

    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 2);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 1);

    if(!glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {
      glfwTerminate();
      cerr << "Cannot open OpenGL 2.1 render context." << endl;
      abort();
    }

    cout << "inited" << endl;

    while (g_run) {
      // rendering something
      cout << "render" << endl;
      this_thread::sleep_for(chrono::seconds(1));
    }
    // unload glfw
    glfwTerminate();
    cout << "quit" << endl;
  });
  __sync_synchronize(); // a barrier added as ildjarn suggested.
  while (g_run) {
    cin >> s;
    cout << "user input: " << s << endl;
    if (s == "q") {
      g_run = false;
      cout << "user interrupt" << endl;
      cout.flush();
    }
  }
  __sync_synchronize(); // another barrier
  t.join();
}

这是我的编译参数:

g++ -std=c++0x -o main main.cc -lpthread -lglfw

我的笔记本电脑运行此程序,如下所示:

My laptop run this program, like this:

init
inited
render
render
q
user input: q
user interrupt
quit

工作站只输出:

init
inited
render
render
q
render
q
render
q
render
^C

它只是简单地忽略了我的输入(另一个程序带有glew和glfw的相同过程,只是跳出了主线程的while循环,而没有读取我的输入.) BUT 这东西在gdb中可以正常使用!

It just simply ignored my inputs (another program same procedure with glew and glfw, just jump out of the while loop in main thread, without reading my inputs.) BUT this thing works normally with gdb!

对正在发生的事情有任何了解吗?

any idea of what's going on?

更新

在其他计算机上进行了更多测试之后,NVIDIA的驱动程序导致了此情况.在装有NVIDIA显卡的其他计算机上也会发生同样的事情.

After more tests on other machines, NVIDIA's driver caused this. Same thing happens on other machines with NVIDIA graphics card.

推荐答案

在其他计算机上进行了更多测试之后,NVIDIA的驱动程序导致了这种情况.在装有NVIDIA显卡的其他计算机上也发生同样的事情.

After more tests on other machines, NVIDIA's driver caused this. Same thing happens on other machines with NVIDIA graphics card.

要解决此问题,初始化顺序需要完成一些工作.在nvidia机器上,必须先初始化glfw(例如,即使您未使用glfw的线程例程,也要创建线程).初始化必须完成,例如,在glfwInit()之后创建输出窗口,否则问题仍然存在.

To fix this problem, there is something to be done with the initialization order. On nvidia machines glfw has to be initialized before anything (eg. create thread, even though you are not using glfw's threading routine.) The initialization has to be complete, say, create the output window after glfwInit(), otherwise the problem persists.

这是固定代码.

#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
#include <GL/glfw.h>

using namespace std;

int main() {
  atomic_bool g_run(true);
  string s;

  cout << "init" << endl;

  if (!glfwInit()) {
    cerr << "Failed to initialize GLFW." << endl;
    abort();
  }

  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 2);
  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 1);

  if(!glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {
    glfwTerminate();
    cerr << "Cannot open OpenGL 2.1 render context." << endl;
    abort();
  }

  cout << "inited" << endl;

  thread t([&]() {
    while (g_run) {
      cin >> s;
      cout << "user input: " << s << endl;
      if (s == "q") {
        g_run = false;
        cout << "user interrupt" << endl;
        cout.flush();
      }
    }
  });

  while (g_run) {
    // rendering something
    cout << "render" << endl;
    this_thread::sleep_for(chrono::seconds(1));
  }

  t.join();

  // unload glfw
  glfwTerminate();
  cout << "quit" << endl;
}

感谢您的所有帮助.

这篇关于C ++ 11&lt; thread&gt;使用OpenGL进行多线程渲染可防止主线程读取stdin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆