如何在 Vala 的循环中使用多个线程共享数据?

How to use multiple threads with shared data inside a loop in Vala?

我想知道如何利用我的核心来并行制作循环 运行。假设我想将一个大数组的所有成员初始化为 1。 为了检查初始化是否正确完成,最后我将数组的所有值相加,但结果为零。如何让线程共享数据?

这是我的尝试:

class Worker {
    public uint64[] arr;
    public uint64 start;
    public uint64 end;
    public int val;

    public Worker (ref uint64[] arr, uint64 start, uint64 end, int val) {
        this.arr = arr;
        this.start = start;
        this.end = end;
        this.val = val;
    }
}

void initialize (Worker p) {
    for (var i = p.start; i <= p.end; i++) {
        p.arr[i] = p.val;
    }
}

int main (string[] args) {

    var num_proc = (int) get_num_processors ();
    stdout.printf ("Using %d threads\n", num_proc);
    uint64 n = 50000000;
    var arr = new uint64[n];
    ulong microseconds;
    double seconds;
    var timer = new Timer ();

    try {
        var threads = new ThreadPool<Worker>.with_owned_data ((ThreadPoolFunc<Worker>) initialize, num_proc, true);
        for (var i = 0; i < num_proc; i++) {
            uint64 start = i * (n / num_proc);
            uint64 end = (i + 1) * (n / num_proc) - 1;
            if (i == num_proc - 1) end += n % num_proc;
            print (@"Thread $(i + 1): start: $start, end: $end (amount: $(end - start + 1))\n");
            threads.add (new Worker (ref arr, start, end, 1));
        }
    } catch (ThreadError e) {
        stderr.printf ("%s\n", e.message);
    }

    uint64 sum = 0;
    for (uint64 i = 0; i < n; i++) {
        sum += arr[i];
    }
    stdout.printf ("sum: %llu\n", sum);

    timer.stop ();
    seconds = timer.elapsed (out microseconds);
    stdout.printf ("Time elapsed: %.3f seconds.\n", seconds);

    return 0;
}

数组复制到这里:

public Worker (ref uint64[] arr, uint64 start, uint64 end, int val) {
    this.arr = arr;
    this.start = start;
    this.end = end;
    this.val = val;
}

作业正在此处创建副本。您可以使用 unowned 变量来解决此问题:

class Worker {
    // The array is not owned by the worker!
    public unowned uint64[] arr;
    public uint64 start;
    public uint64 end;
    public int val;

    public Worker (ref uint64[] arr, uint64 start, uint64 end, int val) {
        this.arr = arr;
        this.start = start;
        this.end = end;
        this.val = val;
    }
}