Jump to page: 1 2
Thread overview
I'm porting some go code to D
Aug 23, 2013
Rory McGuire
Aug 24, 2013
Jesse Phillips
Aug 24, 2013
Rory McGuire
Aug 24, 2013
David
Aug 24, 2013
Rory McGuire
Sep 20, 2013
Sean Kelly
Aug 24, 2013
Moritz Maxeiner
Aug 24, 2013
Rory McGuire
Aug 24, 2013
David Nadlinger
Aug 24, 2013
bearophile
Aug 24, 2013
Jonas Drewsen
Aug 24, 2013
Rory McGuire
Aug 24, 2013
Paulo Pinto
Aug 25, 2013
Rory McGuire
Aug 25, 2013
Rory McGuire
Aug 25, 2013
Timon Gehr
Aug 25, 2013
Rory McGuire
Sep 18, 2013
Rory McGuire
August 23, 2013
So I'm porting so #golang code to #dlang and there is all these blasted
"go" statements.So I thought I'd give implmenting it in D a shot. What do
you guys think?
Fire away :).

import std.stdio;
import core.thread : Thread;
import core.sync.mutex : Mutex;
import core.time;

void main() {
    auto ch = chan!int(1);
    go!({
        foreach (i; 22..44) {
            ch._ = i;
        } });

    foreach (i; 0..10) {
        writeln("pop: ", ch._);
    }
}

// Implementation

void go(alias F)() {
    auto t = new Thread(F);
    t.isDaemon(true); // we don't care if this thread dies.
    t.start();
}

/**
 * chan allows messaging between threads without having to deal with locks,
similar to how chan works in golang
 */
class chan_(T) {
    shared Mutex lock;
    struct Container(T) {
        T value;
        Container!T* next;
    }
    shared Container!T* buf;
    shared Container!T* last;
    shared size_t length;
    shared void insert(shared T v) {
        shared Container!T* newItem = new shared Container!T();
        newItem.value = v;
        if (buf is null) {
            buf = newItem;
            last = newItem;
        } else {
            last.next = newItem;
            last = newItem;
        }
        length++;
    }
    shared T popFront() {
        T ret;
        synchronized (lock) {
            ret = buf.value;
            buf = buf.next;
            length--;
        }
        return ret;
    }
    size_t maxItems;
    bool blockOnFull = false;
    this(int maxItems = 1024, bool blockOnFull = true) {
        lock = cast(shared)new Mutex;
        length = 0;

        this.maxItems = maxItems;
        this.blockOnFull = blockOnFull;
    }

    @property
    shared void _(T value) {
        bool done;
        while(true) {
            synchronized(lock) {
                if (!done && length < maxItems) {
                    insert(value);
                    done = true;
                } else if (!blockOnFull) {
                    throw new ChannelFull("Channel Full");
                }
                if (length <= maxItems-1) {
                    break;
                }
            }
            Thread.sleep(dur!"msecs"(5));
        }
    }
    @property
    shared T _() {
        while(true) {
            size_t len;
            synchronized(lock) {
                len = length;
            }
            if (len > 0) {
                break;
            }
            Thread.sleep(dur!"msecs"(5));
        };
        auto r = popFront();
        return r;
    }
}
auto chan(T)(int n, bool blockOnFull = true) {
    return cast(shared)new chan_!T(n, blockOnFull);
}

class ChannelFull : Exception {
    this(string msg, string file = __FILE__, ulong line =
cast(ulong)__LINE__, Throwable next = null) {
        super(msg,file,line,next);
    }
}


August 24, 2013
On Friday, 23 August 2013 at 23:54:55 UTC, Rory McGuire wrote:
> So I'm porting so #golang code to #dlang and there is all these blasted
> "go" statements.So I thought I'd give implmenting it in D a shot. What do
> you guys think?
> Fire away :).

I'd suggest posting long snippets of code to https://gist.github.com/ or http://dpaste.dzfl.pl/

A couple lines is fine but whole implementations, definitely want a more color friendly solution.
August 24, 2013
On 24 Aug 2013 03:15, "Jesse Phillips" <Jesse.K.Phillips+D@gmail.com> wrote:
>
> On Friday, 23 August 2013 at 23:54:55 UTC, Rory McGuire wrote:
>>
>> So I'm porting so #golang code to #dlang and there is all these blasted
>> "go" statements.So I thought I'd give implmenting it in D a shot. What do
>> you guys think?
>> Fire away :).
>
>
> I'd suggest posting long snippets of code to https://gist.github.com/ or
http://dpaste.dzfl.pl/
>
> A couple lines is fine but whole implementations, definitely want a more
color friendly solution.

Good point.


August 24, 2013
Daemonic Threads often end with a segfault, so if your main thread exists, the other threads will probably segfault.
August 24, 2013
On 24 Aug 2013 11:00, "David" <d@dav1d.de> wrote:
>
> Daemonic Threads often end with a segfault, so if your main thread exists, the other threads will probably segfault.

Thanks, I wonder what they're accessing that they shouldn't.


August 24, 2013
On Friday, 23 August 2013 at 23:54:55 UTC, Rory McGuire wrote:
> So I'm porting so #golang code to #dlang and there is all these blasted
> "go" statements.So I thought I'd give implmenting it in D a shot. What do
> you guys think?
> Fire away :).
>
> /**
>  * chan allows messaging between threads without having to deal with locks,
> similar to how chan works in golang
>  */
> class chan_(T) {
>     shared Mutex lock;
>     struct Container(T) {
>         T value;
>         Container!T* next;

I'm probably missunderstanding somehting about the TLS model, but from what I know, for something like this, shouldn't you make the class instance itself go into shared storage instead instead of all the members?

August 24, 2013
On Friday, 23 August 2013 at 23:54:55 UTC, Rory McGuire wrote:
> So I'm porting so #golang code to #dlang and there is all these blasted
> "go" statements.So I thought I'd give implmenting it in D a shot. What do you guys think?

It's a cute idea, but not really practical, I'm afraid – Goroutines are managed by a scheduler in the Go runtime library, whereas D threads directly map to OS threads. Thus, if the Go application you are porting uses many Goroutines (and the Go code I've seen usually does so very liberally), the performance of the D equivalent is going to be horrible.

David
August 24, 2013
David Nadlinger:

> It's a cute idea, but not really practical, I'm afraid – Goroutines are managed by a scheduler in the Go runtime library, whereas D threads directly map to OS threads.

Can't Rory McGuire add a scheduler to his code? How much code does it take?

Bye,
bearophile
August 24, 2013
On 24 Aug 2013 11:25, "Moritz Maxeiner" <moritz@ucworks.org> wrote:
>
> On Friday, 23 August 2013 at 23:54:55 UTC, Rory McGuire wrote:
>>
>> So I'm porting so #golang code to #dlang and there is all these blasted
>> "go" statements.So I thought I'd give implmenting it in D a shot. What do
>> you guys think?
>> Fire away :).
>>
>> /**
>>  * chan allows messaging between threads without having to deal with
locks,
>> similar to how chan works in golang
>>  */
>> class chan_(T) {
>>     shared Mutex lock;
>>     struct Container(T) {
>>         T value;
>>         Container!T* next;
>
>
> I'm probably missunderstanding somehting about the TLS model, but from
what I know, for something like this, shouldn't you make the class instance itself go into shared storage instead instead of all the members?
>
I have no idea if shared on the class makes all it's parts shared.
It was a struct but I had problems with passing it to the spawn func when I
was using std.concurrent .

I'm trying to port a cassandra cql library from go so it's really just to help with that.

I'm having a hard time imagining how to implement select from go. Could probably use std.concurrent.receive because that can handle multiple types at once.

Sorry I'm rambling...


August 24, 2013
On Saturday, 24 August 2013 at 13:26:32 UTC, bearophile wrote:
> David Nadlinger:
>
>> It's a cute idea, but not really practical, I'm afraid – Goroutines are managed by a scheduler in the Go runtime library, whereas D threads directly map to OS threads.
>
> Can't Rory McGuire add a scheduler to his code? How much code does it take?

It would be very nice to have a builtin scheduler in the runtime. It would make async non-threaded programming so much nicer in D.

/Jonas
« First   ‹ Prev
1 2