2010-09-30 90 views
6

我正在努力從一個額外的線程調用雜波功能。 我使用boost :: thread進行線程和雜亂庫1.0。C++ - Clutter 1.0 - 從線程調用函數導致段錯誤

具體來說,線程包含一個循環函數,每隔一段時間就會發出帶有x和y座標參數的boost :: signals2 :: signal。 該信號被連接到一個函數,它的手在

clutter_stage_get_actor_at_pos(CLUTTER_STAGE(演員), CLUTTER_PICK_ALL,X,Y)的那些變量雜波,即X,Y;

這就是我得到段錯誤的地方。

顯然混亂有一些線程處理例程。我試過打電話

g_thread_init(NULL);

clutter_threads_init();

在啓動clutter_main()之前。我也嘗試在

中包含雜波功能

clutter_threads_enter();

clutter_stage_get_actor_at_pos(CLUTTER_STAGE(actor), 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

因爲您沒有使用任何Boost魔法,所以更改您的代碼以使用pthread而不是boost :: thread,並且此處大多數人都沒有安裝它。 – karlphillip 2010-10-12 18:43:46

回答

0

我玩過你的代碼,看起來你一切都好,雖然我不是Clutter的專家。我也跑你的程序在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 GT上使用了NVIDIA的OpenGL驅動程序。

你能否確認你的應用程序在其他顯卡(不是NVIDIA)的計算機上也崩潰?我懷疑這次崩潰是由於NVIDIA OpenGL實施中的一個錯誤造成的。

對於我來說,似乎* clutter_threads_enter /離開()*不保護* clutter_stage_get_actor_at_pos()*因爲我測試* receive_loop()*被稱爲回調:

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

所以我們知道你的代碼似乎沒問題。

我鼓勵你去你的問題發送到Clutter discussion and help郵件列表:雜波APP-devel的列表

使用雜波基於雜波應用開發商,它的集成庫或工具包郵件列表。

+0

不幸的是,沒有解決我的問題。請參閱我的問題附錄。感謝您的建議! – 2010-10-12 07:27:13

+0

@ verb-sap更新回答。 – karlphillip 2010-10-12 18:31:45

0

我在Python綁定中遇到了一個非常類似的情況,因爲混亂。我從來沒有能夠讓Clutter線程支持以我想要的方式工作。

這個技巧最終是在使用一個空閒的proc(python中的gobject.idle_add)將我需要完成的工作推到主要的混亂線程中。這樣,我只有1個線程使得混亂調用,一切都很好。

6

嗯,我想我找到了答案 ..

Clutter Docs Gerneral

它說,在部分 「線程模型」:

使用雜波的唯一安全和可移植的方法多線程環境中的API決不會從未調用clutter_init()和clutter_main()的線程訪問API。

線程與Clutter一起使用的常見模式是使用工作線程執行阻塞操作,然後在線程完成時安裝空閒或時間源以及結果。

Clutter提供g_idle_add()和g_timeout_add()的線程感知變體,它在調用提供的回調之前獲取Clutter鎖:clutter_threads_add_idle()和clutter_threads_add_timeout()。

所以我的修正最小示例代碼將改變receive_loop()來

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

並添加get_actor功能(如示例代碼menitioned文檔頁)

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 2010-10-18 23:01:35

+0

@karlphillip是的,它現在正常工作 – 2010-10-19 12:59:18

+0

是的,這是正確的答案。 (現在在線程程序中使用Clutter已經有幾年了。) – 2010-11-11 02:03:48

0

您可以使用clutter_threads_add_idle噸o更新ClutterActor或者您需要修復clutter_threads_enter/leave以切換OpenGL上下文,以便您可以在線程內使用它。

崩潰

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 

是因爲調用線程沒有獲得OpenGL上下文,因此墜毀。

相關問題