2012-05-22 25 views
7

यह प्लेटफॉर्म से संबंधित है (मेरे लैपटॉप पर उबंटू 12.04 के साथ काम करता है, मेरे वर्कस्टेशन पर एक और उबंटू 12.04 के साथ काम नहीं करता है)।सी ++ 11 <thread> ओपनजीएल के साथ प्रतिपादन मल्टीथ्रेड्स मुख्य थ्रेड को रोकता है stdin

यह एक नमूना कोड है जो मैं दो धागे के साथ कर रहा हूं।

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

मेरे लैपटॉप रन इस कार्यक्रम, इस तरह::

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

और कार्य केंद्र सिर्फ आउटपुट:

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

यह सिर्फ

#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(); 
} 

यहाँ मेरी संकलन पैरामीटर है बस मेरे इनपुट को नजरअंदाज कर दिया (एक और प्रोग्रा glew और glfw के साथ एक ही प्रक्रिया, मेरे इनपुट को पढ़ने के बिना, मुख्य धागे में बस लूप से बाहर कूदें।) लेकिन यह बात सामान्य रूप से gdb के साथ काम करती है!

क्या हो रहा है इसके बारे में कोई विचार है?

अद्यतन

अन्य मशीनों पर और अधिक परीक्षण के बाद, NVIDIA के ड्राइवर इस का कारण बना। एनवीआईडीआईए ग्राफिक्स कार्ड के साथ अन्य मशीनों पर भी यही बात होती है।

+4

सादे 'बूल 'के बजाय' g_run' a 'std :: atomic ' बनाने का प्रयास करें। – ildjarn

+0

कोशिश की और काम नहीं करता है। इस मामले में कोई रेसिंग स्थिति नहीं है, क्योंकि केवल एक धागा इसे लिख रहा है। – xiaoyi

+7

एक धागा लिख ​​रहा है जबकि दूसरा पढ़ रहा है। आपको ** ** एक स्मृति बाधा की आवश्यकता है। – ildjarn

उत्तर

1

अन्य मशीनों पर और अधिक परीक्षण के बाद से डाटा पढ़ने है, एनवीआईडीआईए के चालक ने इसका कारण बना दिया। एनवीआईडीआईए ग्राफिक्स कार्ड के साथ अन्य मशीनों पर भी यही बात होती है।

इस समस्या को ठीक करने के लिए, प्रारंभिक क्रम के साथ कुछ किया जाना है। एनवीडिया मशीनों पर glfw को किसी भी चीज़ से पहले शुरू किया जाना चाहिए (उदाहरण के लिए, थ्रेड बनाएं, भले ही आप glfw के थ्रेडिंग दिनचर्या का उपयोग नहीं कर रहे हों।) प्रारंभ करना, पूर्ण होना चाहिए, कहें, glfwInit() के बाद आउटपुट विंडो बनाएं, अन्यथा समस्या बनी रहती है।

यहां तय कोड है।

#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; 
} 

धन्यवाद आपकी सभी मदद करता है।

2

मैं जब इसकी runing

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <termios.h> 


static struct termios old, _new; 
static void * breakonret(void *instance); 

/* Initialize _new terminal i/o settings */ 
void initTermios(int echo) 
{ 
tcgetattr(0, &old); /* grab old terminal i/o settings */ 
_new = old; /* make _new settings same as old settings */ 
_new.c_lflag &= ~ICANON; /* disable buffered i/o */ 
_new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */ 
tcsetattr(0, TCSANOW, &_new); /* use these _new terminal i/o settings now */ 
} 

/* Read 1 character with echo */ 
char getche(void) 
{ 
char ch; 
initTermios(1); 
ch = getchar(); 
tcsetattr(0, TCSANOW, &old); 
return ch; 
} 

int main(){ 
pthread_t mthread; 
pthread_create(&mthread, NULL, breakonret, NULL); //initialize break on return 
while(1){ 
    printf("Data on screen\n"); 
    sleep(1); 
} 
pthread_join(mthread, NULL); 
} 
static void * breakonret(void *instance){// you need to press q and return to close it 
char c; 
c = getche(); 
printf("\nyou pressed %c \n", c); 
if(c=='q')exit(0); 
fflush(stdout); 
} 
इस के साथ

मेरा कार्यक्रम को बंद करने और मेरी क्ष कुंजी प्राप्त करने के लिए इस कोड का उपयोग करने पर एक धागा अपने कीबोर्ड

+0

आपके उत्तर के लिए धन्यवाद, यह वास्तव में मेरे दूसरे [प्रश्न] (http://stackoverflow.com/questions/10663407/stop-repl-from-another-thread) के साथ मदद करता है। लेकिन इसके लिए थोड़ा सा विषय लगता है। – xiaoyi