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



Obviously, if the code proposed by Luca was stored separately in its own
file (or in)  library then all one would have to to to use use this
goroutine/channnels/-ike construct boils down to:

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

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;
}
/////////////////////




On Tue, July 12, 2011 at 5:55 AM, Serge Hulne <serge hulne gmail com> wrote:

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]