www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this a good idea?

reply Dr.No <jckj33 gmail.com> writes:
I would to process the current block in parallel but priting need 
to be theread-safe so I'm using

 foreach(x; parallel(arr)) {
    auto a = f(x);
    auto res = g(a);
    synchronized {
	stdout.writeln(res);
	stdout.flush();
     }
 }
Since f() and g() are some heavy functions, I'd like to process in parallel but the printing (doesn't need to respect order but must be thread-safe) hence I'm using synchronized. Is this counter-productive in any way?
Aug 30 2018
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On Thursday, 30 August 2018 at 19:59:17 UTC, Dr.No wrote:
 I would to process the current block in parallel but priting 
 need to be theread-safe so I'm using

 foreach(x; parallel(arr)) {
    auto a = f(x);
    auto res = g(a);
    synchronized {
	stdout.writeln(res);
	stdout.flush();
     }
 }
Since f() and g() are some heavy functions, I'd like to process in parallel but the printing (doesn't need to respect order but must be thread-safe) hence I'm using synchronized. Is this counter-productive in any way?
I don't see any problem with that assuming f and g are significantly more expensive than writeln. The flush can be moved outside the synchronized block.
Aug 30 2018
parent reply Dr.No <jckj33 gmail.com> writes:
On Thursday, 30 August 2018 at 21:09:35 UTC, Peter Alexander 
wrote:
 On Thursday, 30 August 2018 at 19:59:17 UTC, Dr.No wrote:
 I would to process the current block in parallel but priting 
 need to be theread-safe so I'm using

 foreach(x; parallel(arr)) {
    auto a = f(x);
    auto res = g(a);
    synchronized {
	stdout.writeln(res);
	stdout.flush();
     }
 }
Since f() and g() are some heavy functions, I'd like to process in parallel but the printing (doesn't need to respect order but must be thread-safe) hence I'm using synchronized. Is this counter-productive in any way?
I don't see any problem with that assuming f and g are significantly more expensive than writeln. The flush can be moved outside the synchronized block.
why move flush to outside the synchronized block? trying out this approach I found to be ok except in some cases, the output look like that:
outjson = {"barCode":"XXXX1","ade":"1"}
outjson = {"barCode":"XXXX2","ade":"2"}
outjson = {"barCode":"XXXX3","ade":"3"}
outjson = {"barCode":"XXXX4","ade":"4"}
outjson = {"barCode":"XXXX5","ade":"5"}
// and so on... then there is this output:
 outjson = {"barCode":"XXXX20","ade":"20"}♪◙outjson = 
 {"barCode":"XXXXX21","ade":"21"}
within the synchronized block. This is supposed to be:
 outjson = {"barCode":"XXXX20","ade":"20"}
 outjson = {"barCode":"XXXXX21","ade":"21"}
also there's that extra ♪◙ character. Thos sounds memory violation somewhere. This only happens when using parallel. Any guess what's possibily happeing?
Sep 01 2018
parent reply Peter Alexander <peter.alexander.au gmail.com> writes:
On Saturday, 1 September 2018 at 16:20:11 UTC, Dr.No wrote:
 why move flush to outside the synchronized block?
flush should be thread safe. In general, yiu want as little code as possible to run under the lock. Not that important though.
 trying out this approach I found to be ok except in some cases, 
 the output look like that:

...

 also there's that extra ♪◙ character. Thos sounds memory 
 violation somewhere.
 This only happens when using parallel. Any guess what's 
 possibily happeing?
Hard to say without seeing code. Agree it looks like a race.
Sep 01 2018
parent Dr.No <jckj33 gmail.com> writes:
On Saturday, 1 September 2018 at 17:08:25 UTC, Peter Alexander 
wrote:
 On Saturday, 1 September 2018 at 16:20:11 UTC, Dr.No wrote:
 why move flush to outside the synchronized block?
flush should be thread safe. In general, yiu want as little code as possible to run under the lock. Not that important though.
 trying out this approach I found to be ok except in some 
 cases, the output look like that:

...

 also there's that extra ♪◙ character. Thos sounds memory 
 violation somewhere.
 This only happens when using parallel. Any guess what's 
 possibily happeing?
Hard to say without seeing code. Agree it looks like a race.
I'll try to make a reduced version of the program so that your guys can help me find out what's wrong. One guess: In the code:
 foreach(x; parallel(arr)) {
   auto a = f(x);
   auto res = g(a);
   synchronized {
    stdout.writeln(res);
    stdout.flush();
 
     }
assuming res is a class type, is res's adress unique due whole loop execution or it can be overritten by another thread? for example: the writeln() call block is locked until thread3 finish printing, thread2 has just finished and now is waiting for thread3 free the resource but before that happens, thread2 just finish. Can thread2 overrite the res adress in any way? I need clarifation on that to try find out what's wrong with this code. for more info: g() does have the last statement as return new myClass()
Sep 01 2018