Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala
- From: Serge Hulne <serge hulne gmail com>
- To: vala-list <vala-list gnome org>, Luca Bruno <lethalman88 gmail com>
- Subject: Re: [Vala] Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala
- Date: Tue, 12 Jul 2011 09:25:17 +0200
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]