2010-09-30 22 views
6

मैं एक अतिरिक्त थ्रेड से अव्यवस्था फ़ंक्शन को कॉल करने के लिए संघर्ष कर रहा हूं। मैं थ्रेडिंग और क्लटर लाइब्रेरी 1.0 के लिए boost :: thread का उपयोग करता हूं।सी ++ - क्लटर 1.0 - थ्रेड से कॉलिंग फ़ंक्शन segfault

विशिष्ट होने के लिए, थ्रेड में एक लूप फ़ंक्शन होता है जो बूस्ट :: सिग्नल 2 :: सिग्नल उत्सर्जित करता है x और y के पैरामीटर के साथ सिग्नल कुछ समय में समन्वय करता है। यही संकेत एक समारोह से जुड़ा है कि हाथ अव्यवस्था है, यानी एक्स, वाई के लिए उन चर

clutter_stage_get_actor_at_pos (CLUTTER_STAGE (अभिनेता), CLUTTER_PICK_ALL, एक्स, वाई) में;

और यही वह जगह है जहां मुझे एक सीगफॉल्ट मिलता है।

स्पष्ट रूप से अव्यवस्था में कुछ थ्रेड-हैंडलिंग दिनचर्या हैं। मैंने

g_thread_init (NULL) को कॉल करने का प्रयास किया;

clutter_threads_init();

clutter_main() शुरू करने से पहले। मैंने

clutter_threads_enter() में अव्यवस्था फ़ंक्शन को संलग्न करने का भी प्रयास किया;

clutter_stage_get_actor_at_pos (CLUTTER_STAGE (अभिनेता), CLUTTER_PICK_ALL, x, y);

clutter_threads_leave();

लेकिन यह भी चाल नहीं करता है ..

हर संकेत की सराहना की है, अग्रिम धन्यवाद!

परिशिष्ट

मैं सिर्फ मैं क्या कर कोशिश कर रहा हूँ का एक न्यूनतम नमूना जाली। मैंने सुझाव दिया है कि clutter_main() दिनचर्या पहले से ही 'संरक्षित' है। अव्यवस्था के कुछ कार्य अलग-अलग धागे से काम करते हैं (उदाहरण के लिए चरण रंग या अभिनेता की स्थिति निर्धारित करना)। क्या मेरे कोड में अभी भी कुछ गड़बड़ है?

#include <clutter/clutter.h> 
#include <boost/thread.hpp> 


ClutterActor *stage; 
ClutterActor* rect = NULL; 


void receive_loop() 
{ 
while(1) 
{ 
    sleep(1); 
    clutter_threads_enter(); 

    ClutterActor* clicked = clutter_stage_get_actor_at_pos(CLUTTER_STAGE(stage), CLUTTER_PICK_ALL,300, 500); 

    clutter_threads_leave(); 
} 

} 


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

    clutter_init(&argc, &argv); 

g_thread_init(NULL); 
clutter_threads_init(); 


    stage = clutter_stage_get_default(); 
    clutter_actor_set_size(stage, 800, 600); 


rect = clutter_rectangle_new(); 
clutter_actor_set_size(rect, 256, 128); 
clutter_actor_set_position(rect, 300, 500); 
clutter_group_add (CLUTTER_GROUP (stage), rect);  


    clutter_actor_show(stage); 


boost::thread thread = boost::thread(&receive_loop); 


clutter_threads_enter(); 
    clutter_main(); 
clutter_threads_leave(); 

    return 0; 
} 
+0

बूस्ट :: थ्रेड के बजाय pthread का उपयोग करने के लिए अपना कोड बदलें क्योंकि आप किसी भी बूस्ट जादू का उपयोग नहीं कर रहे हैं और यहां अधिकांश लोगों ने इसे इंस्टॉल नहीं किया है। – karlphillip

उत्तर

0

मैंने आपके कोड के साथ खेला और ऐसा लगता है कि आप सब ठीक कर रहे हैं, हालांकि मैं क्लटर में कोई विशेषज्ञ नहीं हूं। मैं भी gdb के तहत अपने कार्यक्रम भाग गया और कुछ दिलचस्प बातें दिखाया:

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb799db70 (LWP 3023)] 
0x002d97c6 in glDisable() from /usr/lib/nvidia-current/libGL.so.1 
(gdb) thread apply all bt 

Thread 2 (Thread 0xb799db70 (LWP 3023)): 
#0 0x002d97c6 in glDisable() from /usr/lib/nvidia-current/libGL.so.1 
#1 0x001b3ec3 in cogl_disable_fog() from /usr/lib/libclutter-glx-1.0.so.0 
#2 0x0018b00a in ??() from /usr/lib/libclutter-glx-1.0.so.0 
#3 0x0019dc82 in clutter_stage_get_actor_at_pos() from /usr/lib/libclutter-glx-1.0.so.0 
#4 0x080498de in receive_loop() at seg.cpp:19 

जाहिर दुर्घटना glDisable() from /usr/lib/nvidia-current/libGL.so.1 पर हुआ। ध्यान दें कि मैं अपने GeForce 8600 जीटी पर एनवीआईडीआईए ओपनजीएल ड्राइवर का उपयोग करता हूं।

क्या आप पुष्टि कर सकते हैं कि आपका एप्लिकेशन अन्य वीडियो कार्ड (एनवीआईडीआईए नहीं) के साथ कंप्यूटर पर भी दुर्घटनाग्रस्त हो जाता है? मुझे संदेह है कि दुर्घटना एनवीआईडीआईए के ओपनजीएल कार्यान्वयन पर एक बग के कारण है।

मेरे लिए यह है कि * clutter_threads_enter/छुट्टी() * की रक्षा नहीं कर रहा है * clutter_stage_get_actor_at_pos (लगता है) * के बाद से मैं * receive_loop() * एक कॉलबैक के रूप में बुलाया जा रहा है परीक्षण किया:

g_signal_connect(stage, "button-press-event", G_CALLBACK(receive_loop), NULL); 

इसलिए हम जानते हैं कि आपके कोड ठीक लगता है।

अव्यवस्था का उपयोग कर आवेदन डेवलपर्स, अपने एकीकरण पुस्तकालयों या उपकरणकिटें अव्यवस्था के आधार पर के लिए एक मेलिंग सूची अव्यवस्था-ऐप्लिकेशन-devel-सूची:

मैं तुम्हें Clutter discussion and help मेलिंग सूची के लिए अपने प्रश्न भेजने के लिए प्रोत्साहित करते हैं।

+0

दुर्भाग्य से मेरी समस्या का समाधान नहीं हुआ। मेरे प्रश्न में मेरा परिशिष्ट देखें। तुम्हारे सुझाव के लिए धन्यवाद! –

+0

@ क्रिया-एसएपी अद्यतन उत्तर। – karlphillip

0

मैंने अव्यवस्था के लिए पाइथन बाइंडिंग में एक बहुत ही समान स्थिति के साथ संघर्ष किया। मैं क्लेटर थ्रेड समर्थन को जिस तरीके से चाहता था उसे काम करने में सक्षम नहीं था।

मुख्य अव्यवस्था धागे में किए गए काम को धक्का देने के लिए चाल आखिरकार एक निष्क्रिय प्रो (gobject.idle_add में पायथन) का उपयोग कर रही थी। इस तरह मेरे पास केवल 1 थ्रेड क्लटर कॉल बना रहा है और सब कुछ ठीक है।

6

ठीक है, मैं मैं जवाब मिल गया लगता है ..

Clutter Docs Gerneral

को अनुभाग में "मॉडल सूत्रण" कहते हैं:

केवल सुरक्षित और पोर्टेबल तरह से अव्यवस्था का उपयोग करने के बहु-थ्रेडेड वातावरण में एपीआई को उस थ्रेड से एपीआई तक कभी भी एक्सेस नहीं करना है जिसने clutter_init() और clutter_main() को कॉल नहीं किया है।

क्लटर के साथ धागे का उपयोग करने के लिए सामान्य पैटर्न ब्लॉकिंग ऑपरेशंस करने के लिए वर्कर थ्रेड का उपयोग करना है और फिर थ्रेड समाप्त होने पर परिणाम के साथ निष्क्रिय या टाइमोर स्रोत स्थापित करना है।

क्लटर g_idle_add() और g_timeout_add() के थ्रेड-जागरूक रूप प्रदान करता है जो प्रदान किए गए कॉलबैक का आविष्कार करने से पहले क्लटर लॉक प्राप्त करता है: clutter_threads_add_idle() और clutter_threads_add_timeout()।

तो कम से कम नमूना कोड के लिए अपने सुधार

void receive_loop() 
{ 
while(1) 
{ 
    sleep(1); 

    int pos[2]; 
    pos[0] = 400; 
    pos[1] = 200; 

    clutter_threads_add_idle_full (G_PRIORITY_HIGH_IDLE, 
          get_actor, 
          &pos, 
          NULL); 
} 
} 

को receive_loop() को बदलने के लिए और (menitioned दस्तावेज़ पृष्ठ पर उदाहरण कोड के रूप में) get_actor समारोह को जोड़ने के लिए किया जाएगा

static gboolean 
get_actor (gpointer data) 
{ 
    int* pos = (int*) data; 
    ClutterActor* clicked = clutter_stage_get_actor_at_pos(CLUTTER_STAGE(stage), CLUTTER_PICK_ALL, pos[0], pos[1]); 

    return FALSE; 
} 

clutter_threads_add_idle_full धागा ताला आदि का ख्याल रखता है ..

+0

क्या यह आपकी समस्या का समाधान करता है? – karlphillip

+0

@karlphillip हाँ यह ठीक काम करता है –

+0

यूप, यह सही जवाब है। (थ्रेड कार्यक्रमों में अब कुछ वर्षों के लिए अव्यवस्था का उपयोग कर रहे थे।) –

0

आप clutter_threads_add_idle टी का उपयोग कर सकते o ClutterActor अपडेट करें या ओपनजीएल संदर्भ को स्विच करने के लिए आपको clutter_threads_enter/leave को ठीक करने की आवश्यकता है ताकि आप इसे थ्रेड के अंदर उपयोग कर सकें।

दुर्घटना

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb799db70 (LWP 3023)] 
0x002d97c6 in glDisable() from /usr/lib/nvidia-current/libGL.so.1 
(gdb) thread apply all bt 

Thread 2 (Thread 0xb799db70 (LWP 3023)): 
#0 0x002d97c6 in glDisable() from /usr/lib/nvidia-current/libGL.so.1 
#1 0x001b3ec3 in cogl_disable_fog() from /usr/lib/libclutter-glx-1.0.so.0 
#2 0x0018b00a in ??() from /usr/lib/libclutter-glx-1.0.so.0 
#3 0x0019dc82 in clutter_stage_get_actor_at_pos() from /usr/lib/libclutter-glx-1.0.so.0 
#4 0x080498de in receive_loop() at seg.cpp:19 

क्योंकि बुला धागे ओपन संदर्भ प्राप्त नहीं किया तो यह दुर्घटनाग्रस्त हो गया है।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^