[Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala



Here is a further development of the idea of Luca Bruno about a Vala
implementation for Generators:

Simulating  Go's goroutines and channels in Vala:

Basically the idea is to start as many threads as needed (which play the
role of Go' goroutines) and to recuperate their output from a "Generator"
(which plays the role of the "Go" channel form which the result from a given
thread can be pulled):

See code hereunder,
Serge.



/////////////////////////////////
using Posix;

abstract class Generator<G> {
    private bool consumed;
    private unowned G value;
    private SourceFunc callback;

    public Generator () {
        helper ();
    }

    private async void helper () {
        yield generate ();
        consumed = true;
    }

    protected abstract async void generate ();

    protected async void feed (G value) {
        this.value = value;
        this.callback = feed.callback;
        yield;
    }

    public bool next () {
        return !consumed;
    }

    public G get () {
        var result = value;
        callback ();
        return result;
    }

    public Generator<G> iterator () {
        return this;
    }
}



class IntGenerator : Generator<int> {
    protected override async void generate () {
        for (int i=0; i < 10; i++) {
             if (i%2 ==0) yield feed (i);
        }
    }
}

class IntGenerator_1 : Generator<int> {
    protected override async void generate () {
        for (int i=0; i < 10; i++) {
             if (i%2 !=0) yield feed (i);
        }
    }
}

IntGenerator    gen;
IntGenerator_1  gen_1;

void* thread_func() {
    //Posix.stdout.printf("Thread running.\n");
    gen = new IntGenerator();
    return null;
}

void* thread_func_1() {
    //Posix.stdout.printf("Thread running.\n");
    gen_1 = new IntGenerator_1();
    return null;
}


int main(string[] args) {

    if (!Thread.supported()) {
        Posix.stderr.printf("Cannot run without threads.\n");
        return 1;
    }

    try {
        unowned Thread<void*> thread = Thread.create<void*>(thread_func,
true);
        thread.join();

        unowned Thread<void*> thread_1 = Thread.create<void*>(thread_func_1,
true);
        thread_1.join();

    } catch (ThreadError e) {
        return 1;
    }

    print("\n\nResults computed in first thread\n");

    var i=0;
    foreach (var item in gen) {
        if (i<10) Posix.stdout.printf("%i\n", item);
        i++;
    }

    print("\n\nResults computed in the second thread\n\n");

    i=0;
    foreach (var item in gen_1) {
        if (i<10) Posix.stdout.printf("%i\n", item);
        i++;
    }


    return 0;
}

/////////////////////////////////


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]