Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在另一个线程中执行Gtk.ListBox.insert和Gtk.ListBox.append会导致Vala程序出错_Multithreading_Listbox_Segmentation Fault_Vala - Fatal编程技术网

Multithreading 在另一个线程中执行Gtk.ListBox.insert和Gtk.ListBox.append会导致Vala程序出错

Multithreading 在另一个线程中执行Gtk.ListBox.insert和Gtk.ListBox.append会导致Vala程序出错,multithreading,listbox,segmentation-fault,vala,Multithreading,Listbox,Segmentation Fault,Vala,我正在用Vala编写一个使用Gtk.ListBox的程序。其中有一个函数,它使用insert()。在某一点上(有不同数量的子对象,但最终会发生),程序会以分段错误终止。这正是在执行insert()函数时发生的,我尝试添加一些print()函数以了解分段错误的原因。我还尝试用append()替换insert()(我知道它们是不同的函数,我只是想检查程序是否会出错),结果是一样的 下面是我正在使用的函数: public new void prepend(MediaInfo post) { G

我正在用Vala编写一个使用Gtk.ListBox的程序。其中有一个函数,它使用insert()。在某一点上(有不同数量的子对象,但最终会发生),程序会以分段错误终止。这正是在执行insert()函数时发生的,我尝试添加一些print()函数以了解分段错误的原因。我还尝试用append()替换insert()(我知道它们是不同的函数,我只是想检查程序是否会出错),结果是一样的

下面是我正在使用的函数:

public new void prepend(MediaInfo post)
{
    Gtk.Separator separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
    base.insert (separator, (int) this.get_children().length () - 1);
    PostBox box = new PostBox(post);
    base.insert (box, (int) this.get_children().length () - 1);
    boxes.append(box);      
}
(PostBox是从Gtk.EventBox继承的类,MediaInfo是我在程序中使用的类,它包含一些在PostBox构造函数中使用的信息,Box是PostBox对象的列表)

我在for循环中使用这个函数,所以它不是添加一个框,而是添加许多框,并且在某些点上程序会出现错误

它似乎与我正在使用的MediaInfo类或PostBox类无关,因为有几次它是在添加Gtk.Separator时发生的

你能告诉我我的代码有什么问题吗?我完全不知道如何处理它


UPD:显然这与线程有关,因为我在程序中使用线程,在用函数调用替换所有创建的线程之后,问题就消失了。

所有对GDK和GTK+的调用都应该从主线程进行。通过使用
GLib.Idle.add
,使用Vala很容易做到这一点,特别是如果您记住Vala支持闭包:

// Do stuff in your thread (CPU-intensive processing, I/O, etc.)
var value = blocking_operation ();

GLib.Idle.add (() => {
    // You can access local variables, like value, here.
    widget.set_something (value);

    // Returning false means the idle callback will be removed automatically
    // after it is called (instead of being called repeatedly).
    return false;
  });
基本上,您要做的是在其他线程中运行任务,完成任务后切换回主线程(使用空闲回调)以修改GTK+内容


也就是说,我认为您可以安全地修改GTK+尚未绘制的任何层次结构中没有的小部件。因此,您可以在线程中实例化一个容器,添加一堆子线程,等等,然后将其添加到主线程的窗口中。不要更改GTK+当前试图绘制的任何内容。

您能生成一个最小的出错程序吗?你能用gdb识别segfault的位置吗?@apmasell我试图删除所有加载函数,并重写了prepend()函数,完全不使用PostBox类,只添加了两个分隔符。结果还是一样。我上传到这里:@apmasell,不幸的是,我不知道如何将gdb与Vala一起使用。但我试图添加一些print()函数来检查程序在哪几行代码之后出错,而我使用append()或insert()函数的肯定是这几行。@apmasell抱歉,我发布了错误的链接,这是对的:太大了,无法最小化。如果您使用
--debug
进行编译,gdb将与Vala“一起工作”。我尝试将所有Gtk操作移动到Idle.add,它工作得非常好!这就是我要找的!非常感谢:)