Re: Using objects that manage threads via std.concurrency

2013-02-12 Thread monarch_dodra
On Tuesday, 12 February 2013 at 07:07:21 UTC, Jonathan M Davis 
wrote:
Which I don't think was ever really intended. That doesn't mean 
that it's
unreasonable, but I think that it was always the idea that a 
particular thread
had a particular job, in which case, you wouldn't generally be 
trying to send

messages to different parts of the thread.

- Jonathan M Davis


Hum, I just realized that receive works out of order on the 
types requested. I thought it *had* to receive THE first message 
in the queue, and throw if the type is not supported.


I guess then that by specifying my specific type, and having a 
dedicated dispatcher, I can make my program work, without 
clashing with anybody else who is also threading.


Now, I've just got to figure out how to manage my master's 
mailbox sizes, if a worker is faster than the rest.


Re: Using objects that manage threads via std.concurrency

2013-02-12 Thread monarch_dodra

On Tuesday, 12 February 2013 at 10:08:14 UTC, FG wrote:

On 2013-02-12 07:58, monarch_dodra wrote:
I think I didn't explain myself very well. I have my single 
master thread
which has a thread-global mailbox, but I have 3 different 
objects that are

sharing that mailbox.


OK, I finally get what you are saying.
You need to create a mailbox and a unique tid for every Manager 
(and probably would have to change Manager into a class). 
Unfortunately this won't work out of the box, as for example 
receiveOnly and friends use only the default mailbox of the 
current thread.


struct Manager
{
Tid tid;
MessageBox mbox;
this(string s)
{
this.mbox = new MessageBox
tid = Tid(new Mailbox);
spawn(worker, s, tid);
}
string get()
{
// you'd have to rewrite receive to use custom mbox
return tid.myReceiveOnly!string();
}
}


Hum, I'll have to try to play around with that. For one thing, 
MessageBox is private.


Good news is my manager is already a class.

As for the re-implement of receive to work on a custom Tid, maybe 
it might be better to forget about the tid, and implement it on 
directly on the mailbox? Something like this:


//
struct Manager
{
MessageBox mbox;
this(string s)
{
this.mbox = new MessageBox
Tid managerTid = Tid(new Mailbox);
spawn(worker, s, managerTid);
}
string get()
{
// you'd have to rewrite receive to use custom mbox
return mbox.receiveOnly!string();
//Or just straight up:
mbox.get();
}
}
//

I don't know, I'll try and see how it goes.


Re: Using objects that manage threads via std.concurrency

2013-02-12 Thread FG

On 2013-02-12 12:14, monarch_dodra wrote:

For one thing, MessageBox is private.


Unnecessarily hidden, because, from what I can see from a fast look at the 
sources, there is no implicit requirement for there to be only one MessageBox 
per thread. Maybe we're getting somewhere and this will be changed.



As for the re-implement of receive to work on a custom Tid, maybe it might be
better to forget about the tid, and implement it on directly on the mailbox?


Well, yes. It's more natural to work on mbox than some artificial struct.

Now, as for the usefulness of having many mailboxes. I'd rather have one mailbox 
than go into a loop with receiveTimeout called for each Manager, but in your 
divideconquer example receive makes sense and keeps ordering.


Using objects that manage threads via std.concurrency

2013-02-11 Thread monarch_dodra
I've been trying out std.concurrency, and it's MPI, and found it 
very easy to use. It has been working well in most of my toy 
programs so far, but I see a HUGE glaring flaw with it. I mean: 
SHOWSTOPPER.


Basically, I can't help but feel the thing has an hopelessly 
thread-global mailbox approach to the problem. This is all fine 
and dandy if there is only a single canal of communication 
between the master and the child/children.


But what happens if you have 2 objects at once that want to 
communicate with their children? They have to share the global 
mailbox, making things very complex.


In my program, I have simple objects: Managers, that spawn a 
child thread to do work. This works fine if I have a single 
Manager, but how do I manage having 2 Managers at once? What 
should a manager do if it calls receive, and notices the 
message wasn't meant for him?


I can write an internal service that can manage the mailbox for 
all my managers, but that is a *very* closed approach. In 
particular, I'm planning to distribute a module with integrated 
multithreading. What if my clients also want to do MPI on their 
end? How does that work?




Is there any way for an object to create its own personal 
MailBox? How would you tackle the problem? Does any one have any 
(simple) literature on the subject?


Re: Using objects that manage threads via std.concurrency

2013-02-11 Thread FG

On 2013-02-11 22:37, monarch_dodra wrote:

Basically, I can't help but feel the thing has an hopelessly thread-global
mailbox approach to the problem. This is all fine and dandy if there is only a
single canal of communication between the master and the child/children.


What thread-global? Every mbox is in thread-local storage.


But what happens if you have 2 objects at once that want to communicate with
their children? They have to share the global mailbox, making things very 
complex.


Caller locks the callee mailbox for a moment to put a message. Doesn't lock any 
other thread, so you can have N/2 threads writing to other N/2 at the same time.



In my program, I have simple objects: Managers, that spawn a child thread to
do work. This works fine if I have a single Manager, but how do I manage having
2 Managers at once?


It's generally a very bad idea to have more than 1 manager over one's head. :)


What should a manager do if it calls receive, and notices the message wasn't
meant for him?


Don't know. Kill the messenger perhaps? :)




Re: Using objects that manage threads via std.concurrency

2013-02-11 Thread Ali Çehreli

On 02/11/2013 01:37 PM, monarch_dodra wrote:

 What should a manager do if it
 calls receive, and notices the message wasn't meant for him?

Threads receive their own messages. If there is a specific receiver of a 
message, then the child sends it to that receiver. As FG said, every 
thread has a separate mailbox.


It is possible to introduce threads to each other by their thread ids, 
which can be mapped to arbitrary names. (See register, locate, and 
unregister in std.concurrency.)


 Does any one have any (simple) literature on the subject?

My experiments have been documented in the following chapter:

  http://ddili.org/ders/d.en/concurrency.html

The Thread names section in there has a simple example that involves a 
third party introducing two threads to each other.


Ali



Re: Using objects that manage threads via std.concurrency

2013-02-11 Thread monarch_dodra

On Tuesday, 12 February 2013 at 00:09:40 UTC, FG wrote:

On 2013-02-11 22:37, monarch_dodra wrote:
Basically, I can't help but feel the thing has an hopelessly 
thread-global
mailbox approach to the problem. This is all fine and dandy 
if there is only a
single canal of communication between the master and the 
child/children.


What thread-global? Every mbox is in thread-local storage.


Yes, but there is only one global mailbox per thread. If I have 
more than one class instance inside a thread trying to 
communicate with other threads, they have to share the box.


But what happens if you have 2 objects at once that want to 
communicate with
their children? They have to share the global mailbox, making 
things very complex.


Caller locks the callee mailbox for a moment to put a message. 
Doesn't lock any other thread, so you can have N/2 threads 
writing to other N/2 at the same time.


I think there is a misunderstanding about what I meant by global 
mailbox.


In my program, I have simple objects: Managers, that spawn a 
child thread to
do work. This works fine if I have a single Manager, but how 
do I manage having

2 Managers at once?


It's generally a very bad idea to have more than 1 manager over 
one's head. :)


What should a manager do if it calls receive, and notices 
the message wasn't

meant for him?


Don't know. Kill the messenger perhaps? :)


Re: Using objects that manage threads via std.concurrency

2013-02-11 Thread Jonathan M Davis
On Tuesday, February 12, 2013 07:58:04 monarch_dodra wrote:
 How can I get my 3 managers to co-exist, when they are all
 sharing the same box? How can I make sure the workers are sending
 their messages to the correct manager?

By making it so that their receiving functions take unique types. If need be, 
you can declare types specific to the channel of communication that you're 
trying to create. Then only functions which match will receive those messages.

  It is possible to introduce threads to each other by their
  thread ids, which can be mapped to arbitrary names. (See
  register, locate, and unregister in std.concurrency.)
 
 Yes, but in this case, the problem is not thread to thread
 communication, but rather thread to object

Which I don't think was ever really intended. That doesn't mean that it's 
unreasonable, but I think that it was always the idea that a particular thread 
had a particular job, in which case, you wouldn't generally be trying to send 
messages to different parts of the thread.

- Jonathan M Davis