2010-09-30 88 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上下文,因此坠毁。

相关问题