On 05/10/2014 06:28 PM, TheFlyingFiddle via Digitalmars-d-learn wrote:
On Friday, 9 May 2014 at 23:12:44 UTC, Charles Hixson via Digitalmars-d-learn wrote:

But I'm worried about the receiving end. It needs, somehow, to ensure that the message it receives is the appropriate message, and that other messages don't get dropped while it's waiting for the answer...or, perhaps worse, substituted for the expected answer. If I can depend on msg[0] of "auto msg = receiveOnly!(Tid, bool)" that will allow me to check that the message was received from the proper source

If you are worried that other messages having the same signature will be sent from other sources than the expected source you could make use of message tagging. Simply wrap the boolean result in a struct with a descriptive name.

struct SharedHashMapSetCB { bool flag; }
void set (string s, uint64_t id)
{
   tbl[s] = id;
   send (SharedHashMapSetCB(true));
}

//On the receiving end
auto msg = receiveOnly!SharedHashMapSetCB();

But doesn't this design lock the entire hash-table while the update is in progress? Is there a better way?
I think a shared memory hash-map is better for your use case. Working with message passing is preferable done asynchronously. Blocking calls (send followed by receive) is likely to be slower then simply waiting on a semaphore.
I think you're probably right. It should be a fairly fast lookup anyway, and since there should be only one copy of the table, I don't think one would get much of a speedup no matter what one did. OTOH, it can't be directly shared. What can be shared is a handle to a singleton synchronized class. Its requirement that it can be updated, IIUC, means that it can't be directly shared.

OTOH... I think I may need to build a mailbox class, the design I'm not yet sure about, that acts as an interface between the major number of threads and each other. Access to it needs to be non-blocking (essentially) so it had probably better ONLY act as a message switchboard. I want it to pass messages with "time" and "origin" (thread id) prefixed to them. OTOH, I probably only need to support a small number of message formats, perhaps two, perhaps three. And it would be more efficient if whenever a thread polled it, it responded with all waiting mail for that destination. So it's only sending in response to a received message directed at it, but it holds all messages directed at some other thread. This allows the other threads to loop through their processing, only occasionally pausing to check whether they have any mail or not. I'm hoping a couple of ms will be a long enough timeout. The mailbox could spend most of it's time sitting blocked at receive.

This isn't the design I was thinking about earlier, but it seems better, and it's the design I originally ended up with the last time I thought about this problem seriously, though admittedly I never got around to implementing it. The question in my mind is "is it better to build this on top of std.concurrency, or to go back to the thread class. The code of std.concurrency shows pretty clearly how to build a mailbox, but the one that it builds doesn't store the things that I want, and is a lot more flexible than I have any use for. Still, it's being maintained as a part of the language...but it's a private class, so I can't use it directly. But threading is difficult and error prone, so it might be better to write a layer on top of std.concurrency, even if it means I need to re-implement a lot of what has already been done.

--
Charles Hixson

Reply via email to