【问题标题】:How do I add to a GLib.List from different Thread in Vala如何从 Vala 中的不同线程添加到 GLib.List
【发布时间】:2023-04-06 21:14:02
【问题描述】:

我有一个要添加元素的 GLib.List。
我想使用多个 GLib.Threads 同时添加这些元素

我正在尝试使用 GLib.Mutex 同步对列表的访问。同步似乎有效,但没有添加任何元素。

public static void main() {
    var list = new GLib.List<string>();
    var mutex = GLib.Mutex();

    var workerA = new Worker("A", list, mutex);
    var workerB = new Worker("B", list, mutex);
    var workerC = new Worker("C", list, mutex);

    GLib.Thread<void*> tA = new GLib.Thread<void*>("WorkerThread", workerA.run);
    GLib.Thread<void*> tB = new GLib.Thread<void*>("WorkerThread", workerB.run);
    GLib.Thread<void*> tC = new GLib.Thread<void*>("WorkerThread", workerC.run);

    tA.join();
    tB.join();
    tC.join();

    stdout.printf("List:\n");
    foreach (string str in list) {
        stdout.printf(" - %s\n", str);
    }
}

class Worker : GLib.Object {
    private string name;
    private weak GLib.List<string> list;
    private weak GLib.Mutex mutex;

    public Worker(string name, GLib.List<string> list, GLib.Mutex mutex) {
        this.name = name;
        this.list = list;
        this.mutex = mutex;
    }

    public void* run() {
        mutex.lock();
        list.append(name);
        mutex.unlock();

        return null;
    }
}

当我查看同步部分时,它似乎工作正常(即使有更多线程),但没有元素被添加到列表中!

输出:

列表:

谁能告诉我怎么做?

【问题讨论】:

    标签: multithreading glib vala


    【解决方案1】:

    GLib.List 有点奇怪。 append 方法实际上修改了指针list,而不是它指向的东西。如果你想让它工作,你需要:

    1. 将列表放在共享位置(例如,使其成为所有线程共享的类的字段或全局变量)。
    2. 请改用 libgee 包中的 Gee.List。一般来说,libgee 中的数据结构在 Vala 中比在 glib 中的对应部分更容易使用。

    【讨论】:

      【解决方案2】:

      感谢 apmasell 指出问题实际上是 GLib.List 我查看了 C source code

      他是对的:append 方法修改了指针 - 但只有 (!) 如果 GLib.List 为空!
      因此,除了使列表成为全局变量或使用另一个列表实现之外,我认为最好的解决方法是在将列表传递给线程之前简单地添加一个元素。
      完成所有线程后,您可以再次删除该元素。

      【讨论】:

      • 调用 append 是一个 O(N) 操作。最好调用 prepend(即 O(1)),然后在完成后反转列表。当然,这会弄乱您在上面描述的 hack — 也许您应该只使用 GLib.Sequence 或 GLib.Tree,它们没有奇怪的语义并且都是 O(log N) 的插入时间。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-05
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多