Thread overview
Threads and stdio and HANDLE
Jan 28, 2015
Danny
Jan 28, 2015
Kagamin
Jan 29, 2015
Nicholas Wilson
January 28, 2015
Hello,

I'm trying to write some toy examples using threads in D.

Is the std.stdio.File thread-local or shared? Is flockfile used when I synchronize on it?

I tried checking phobos myself and found some things I don't get (in stdio.d):

alias FLOCK = flockfile;

this(this) { @trusted
  if(fps_)
    FLOCK(fps_);
}

What is "this(this)"?

If I want to write to stdout from a thread, do I use LockingTextWriter? File? shared File? Does each thread have the same stdout? (Ok I checked, they have the same address, so probably. Phobos has it as __gshared stdout, aha)

Also, in order to avoid all that (also I want to be able to set Console text attributes on Windows), I tried to use the lowlevel I/O next:

For UNIX, the fds are per-process and just integers. So I know there that I can just pass around the int fd to any threads.

For Windows, if I use GetStdHandle, is the resulting HANDLE valid for threads other than the one that called GetStdHandle ? Because the HANDLE is a pointer but doesn't have "shared". Does one know for Windows handles in general which are per-thread and which are per-process ?

Finally, I'm trying to come to grips with "shared":

The first use of shared is to signal to the compiler that it should not store the variable in thread-local storage. But when I acquire a lock (using "synchronized", say), I'm supposed to cast away the "shared", right? Does it then still know that it's not thread-local (but that I ensured that nobody else accesses it for the time being)?

What does specifying "shared class" or "shared struct" do?
January 28, 2015
On Wednesday, 28 January 2015 at 11:50:46 UTC, Danny wrote:
> For Windows, if I use GetStdHandle, is the resulting HANDLE valid for threads other than the one that called GetStdHandle ? Because the HANDLE is a pointer but doesn't have "shared". Does one know for Windows handles in general which are per-thread and which are per-process ?

There are no per-thread handles in windows. HANDLE was a pointer during DOS days, but its implementation changed to use indexes like on unix.
January 29, 2015
On Wednesday, 28 January 2015 at 11:50:46 UTC, Danny wrote:
> Hello,
>
> I'm trying to write some toy examples using threads in D.
>
> Is the std.stdio.File thread-local or shared? Is flockfile used when I synchronize on it?
>
> I tried checking phobos myself and found some things I don't get (in stdio.d):
>
> alias FLOCK = flockfile;
>
> this(this) { @trusted
>   if(fps_)
>     FLOCK(fps_);
> }
>
> What is "this(this)"?
>
this(this) is the constructor syntax for construction of an already
 initialised struct. (sort of equivalent to the C++
class foo {
    foo(const foo& other)
    {
        ...
    }
} )

used like
 struct somestruct
{
    ...
    this()
    {
        writeln("calling this()");
    }
    this(this)
    {
        writeln("calling this(this)");
    }
}
...
auto foo = somestruct(); //prints calling this()
auto baz = foo;              //prints calling this(this)

> If I want to write to stdout from a thread, do I use LockingTextWriter? File? shared File? Does each thread have the same stdout?
Yes

>
> Finally, I'm trying to come to grips with "shared":
>
> What does specifying "shared class" or "shared struct" do?

all methods are marked as shared
(similar to what final class quux { ... } does compared to just class quux { ... } )

> The first use of shared is to signal to the compiler that it should not store the variable in thread-local storage. But when I acquire a lock (using "synchronized", say), I'm supposed to cast away the "shared", right?
IIRC ,yes.
as in
class Bar { ... }
auto foo(shared Bar bar)
{
    synchronized(bar) //acquire lock
    {
        Bar not_shared_bar = cast(Bar) bar;
        ...
        //use not_shared_bar here as thread local.
        // No races can occur because of the lock.
        // DO NOT allow references to non_shared_bar to escape
        // as using them outside the synchronised could lead to racing
    }
}
> Does it then still know that it's not thread-local (but that I ensured that nobody else accesses it for the time being)?
>
No. it's up to you to make sure that no non-shared references escape