www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to handle shared arrays?

reply maarten van damme <maartenvd1994 gmail.com> writes:
I want to have two threads. One parses some content ever half hour and
the other continuously parses commands passed from the first thread.
When the second thread finished something it should send the results
back to the first thread who'll present it to the user.
The messages the second thread needs to send back is under the form of
an array of a struct.

Right now I'm trying something like this:
			shared (T[]) mods=cast(shared (T[]))modifications.dup;
			send(tid, mods);

This gives me a rather odd-looking errormessage:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: function core.
stdc.string.memcpy (void* s1, const(void*) s2, uint n) is not callable using arg
ument types (ubyte[20u]*,shared(T[])*,uint)
C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: cannot implici
tly convert expression (& rhs) of type shared(T[])* to const(
void*)

How should I handle arrays that I will need to send back to another thread?
Excuse me for all those questions, I'm really having a hard time
grasping the D threading model.
Jun 21 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/21/2012 12:00 PM, maarten van damme wrote:
 I want to have two threads. One parses some content ever half hour and
 the other continuously parses commands passed from the first thread.
 When the second thread finished something it should send the results
 back to the first thread who'll present it to the user.
 The messages the second thread needs to send back is under the form of
 an array of a struct.

 Right now I'm trying something like this:
 			shared (T[]) mods=cast(shared (T[]))modifications.dup;
 			send(tid, mods);

 This gives me a rather odd-looking errormessage:
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: 
function core.
 stdc.string.memcpy (void* s1, const(void*) s2, uint n) is not 
callable using arg
 ument types (ubyte[20u]*,shared(T[])*,uint)
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\variant.d(528): Error: 
cannot implici
 tly convert expression (&  rhs) of type shared(T[])* to const(
 void*)

 How should I handle arrays that I will need to send back to another 
thread?
 Excuse me for all those questions, I'm really having a hard time
 grasping the D threading model.
I know I am not answering your question precisely, but how about sending an immutable array? If the owner does not need to modify what the worker sends, you can pass a slice of immutable(Result) objects. assumeUnique works is useful for the worker to convert its mutable array to an immutable one: import std.stdio; import std.exception; import std.concurrency; struct Command {} struct Result {} struct Exit {} void workerFunc(Tid owner) { bool isDone = false; while (!isDone) { receive( (Command command) { writeln("worker - received command"); Result[] results = [ Result(), Result() ]; writeln("worker - sending results"); owner.send(assumeUnique(results)); }, (Exit message) { writeln("worker - exiting"); isDone = true; }); } } void main() { auto worker = spawn(&workerFunc, thisTid); foreach (i; 0 .. 3) { writeln("main - sending command ", i); worker.send(Command()); auto results = receiveOnly!(immutable(Result)[])(); writeln("main - received results: ", results); } writeln("main - stopping worker"); worker.send(Exit()); } The output: main - sending command 0 worker - received command worker - sending results main - received results: [immutable(Result)(), immutable(Result)()] main - sending command 1 worker - received command worker - sending results main - received results: [immutable(Result)(), immutable(Result)()] main - sending command 2 worker - received command worker - sending results main - received results: [immutable(Result)(), immutable(Result)()] main - stopping worker worker - exiting Ali -- D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
Jun 21 2012
parent reply maarten van damme <maartenvd1994 gmail.com> writes:
Oh thank god, this helps soo much. Now I can finally do away with all
those ugly shared casts and variables in my other toy code involving
threads.
It works like a charm, great.
Jun 21 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 06/21/2012 02:30 PM, maarten van damme wrote:
 Oh thank god, this helps soo much.
Yay! :) Thinking more about it, assumeUnique is a more general solution which may not be needed in every case. As long as the worker is happy with an immutable(Result) slice, the following delegate works as well. No more assumeUnique: (Command command) { writeln("worker - received command"); immutable(Result)[] results; results ~= immutable(Result)(); results ~= immutable(Result)(); writeln("worker - sending results"); owner.send(results); }, Ali
Jun 21 2012