我有一个我要添加元素的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;
}
}
当我查看同步部分时,它似乎工作正常(即使有更多的线程),但没有元素被添加到列表中!
输出:
列表:
有人可以告诉我怎么做吗?
答案 0 :(得分:1)
GLib.List
有点奇怪。 append
方法实际上修改了指针list
,而不是它指向的东西。如果你想要这个,你需要:
Gee.List
代替。一般来说,在vala中的数据结构比在glib中的对应部分更容易在Vala中使用。答案 1 :(得分:0)
感谢 apmasell 指出不起作用的事实上是GLib.List
我看了C source code。
他是对的:如果append
为空,GLib.List
方法会修改指针 - 但仅(!)!
因此,除了使列表成为全局变量或使用其他列表实现之外,我认为最好的工作方法是在将列表传递给线程之前简单地添加一个元素。
完成所有线程后,您只需再次删除该元素即可。