Simplest multithreading example

Brian via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Aug 31 22:27:40 PDT 2017


On Friday, 1 September 2017 at 04:43:29 UTC, Ali Çehreli wrote:
> On 08/31/2017 06:59 PM, Brian wrote:
> > Hello, I am trying to get the most trivial example of
> multithreading
> > working, but can't seem to figure it out.
> > I want to split a task across threads, and wait for all those
> tasks to
> > finish before moving to the next line of code.
> >
> > The following 2 attempts have failed :
> >
> > -----------------------------------------------------
> > Trial 1 :
> > -----------------------------------------------------
> >
> > auto I = std.range.iota(0,500);
> > int [] X; // output
> > foreach (i; parallel(I) )
> >     X ~= i;
> > core.thread.thread_joinAll(); // Apparently no applicable
> here ?
>
> As Michael Coulombe said, parallel() does that implicitly.
>
> If the problem is to generate numbers in parallel, I 
> restructured the code by letting each thread touch only its 
> element of a results array that has already been resized for 
> all the results (so that there is no race condition):
>
> import std.stdio;
> import std.parallelism;
> import std.range;
>
> void main() {
>     auto arrs = new int[][](totalCPUs);
>     const perWorker = 10;
>     foreach (i, arr; parallel(arrs)) {
>         const beg = cast(int)i * perWorker;
>         const end = beg + perWorker;
>         arrs[i] = std.range.iota(beg,end).array;
>     }
>
>     writeln(arrs);
> }
>
> If needed, std.algorithm.joiner can be used to make it a single 
> sequence of ints:
>
>     import std.algorithm;
>     writeln(arrs.joiner);
>
> Ali

Hello, thank you very much for your quick replies !

I was trying to make a trivial example, but the 'real' problem is 
trying to split a huge calculation to different threads.

Schematically :

double [] hugeCalc(int i){
     // Code that takes a long time
}

so if I do


double[][int] _hugeCalcCache;
foreach(i ; I)
    _hugeCalcCache[i] = hugeCalc(i);

of course the required time is I.length * (a long time), so I 
wanted to shorten this by splitting to different threads :

foreach(i ; parallel(I) )
    _hugeCalcCache[i] = hugeCalc(i);

but as you can guess, it doesn't work that easily.

Very interesting approach about letting only the thread touch a 
particular element, I will try that.

FYI I did manage to make the following work, but not sure if this 
is really still multi-threaded ?


	int [] I;
	foreach (i; 0 .. 500) I ~= i;
	int [] X; // output
	class DerivedThread : Thread {
		private int [] i;
		this(int [] i){
			this.i = i;
			super(&run);
		}
		private void run(){
			synchronized{ // Need synchronization here !
				foreach( i0; i)
					X ~= i0;
			}
		}
	}
	Thread [] threads;
	foreach (i; std.range.chunks( I, 50 ) )
		threads ~= new DerivedThread( i);
	foreach( thread; threads)
		thread.start();
	
	core.thread.thread_joinAll(); // Does in fact seem to 'join all' 
threads
	writeln(X);


More information about the Digitalmars-d-learn mailing list