www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Threading

reply Brok3n Halo <brokenhalo282 gmail.com> writes:
Hi

I'm new do D and am getting the hang of things for the most part, but I can't
get threading to work at all.  I couldn't find any examples specific to D 1.0
but seeing that the documentation look similar outside of the example for D2,
I followed the example at
http://www.digitalmars.com/d/2.0/phobos/std_thread.html#Thread

I tried it both was shown, but it doesn't seem to work as documented there,
probably due to changes from 1.0 to 2.0.

I attached the code I derived for one of the two ways, both had the same
result though of the method I want to be threaded just running in the main
thread when the thread object is initialized.

I'm using ReBuild 0.78 (based on DMD 2.019) from Eclipse Descent on the
Windows 7 Beta.

The output of the program looks like this:
Error: Win32 Exception
1
2
3
4
5
6
7
8
9
10
WTF!
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI
OH HAI

Any help would be awesome, thanks.
begin 644 test.d
M;6]D=6QE('1E<W0[#0H-"FEM<&]R="!S=&0N=&AR96%D.PT*:6UP;W)T('-T
M9"YS=&1I;SL-" T*#0IS=&%T:6, :6YT(&-O=6YT(#T ,#L-" T*=F]I9"!M
M86EN*"E[#0H-" E4:')E860 =&5S='1H<F5A9#L-" T*"75I;G0 =&5S=&9U
M;F,H*7L-" D)=VAI;&4H8V]U;G0\,3`I>PT*"0D)*RMC;W5N=#L-" D)"7=R
M:71E9FQN*"(E9"(L(&-O=6YT*3L-" D)?0T*"0ER971U<FX ,#L-" E]#0H-
M" T*"71E<W1T:')E860 /2!N97< 5&AR96%D*'1E<W1F=6YC*3L-" EW<FET
M969L;B B5U1&(2(I.PT*"71E<W1T:')E860N<W1A<G0H*3L-" T*"69O<BAI
M;G0 :2`](#`[(&D\,3`[("LK:2E[#0H)"7=R:71E9FQN*")/2"!(04DB*3L-
*" E]#0H-" T*?0``
`
end
May 11 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 May 2009 08:11:22 -0400, Brok3n Halo <brokenhalo282 gmail.com>  
wrote:

 Hi

 I'm new do D and am getting the hang of things for the most part, but I  
 can't
 get threading to work at all.  I couldn't find any examples specific to  
 D 1.0
 but seeing that the documentation look similar outside of the example  
 for D2,
 I followed the example at
 http://www.digitalmars.com/d/2.0/phobos/std_thread.html#Thread

 I tried it both was shown, but it doesn't seem to work as documented  
 there,
 probably due to changes from 1.0 to 2.0.

 I attached the code I derived for one of the two ways, both had the same
 result though of the method I want to be threaded just running in the  
 main
 thread when the thread object is initialized.

 I'm using ReBuild 0.78 (based on DMD 2.019) from Eclipse Descent on the
 Windows 7 Beta.

 The output of the program looks like this:
 Error: Win32 Exception
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 WTF!
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
 OH HAI
A victim of the property syntax :) At this line: testthread = new Thread(testfunc); Try this instead: testthread = new Thread(&testfunc); Note that due to the property syntax sugar of D, typing just the function name of a no-parameter function is the same as if you put the parentheses, i.e. testfunc is the same as testfunc(). So you were calling testfunc, passing the result (which is a uint) to the constructor for Thread (which is probably what caused the exception), and then running the thread. This is why you get the count-to-10 before WTF. Putting the address (&) symbol before the function is now passing the function delegate (a way to call the function) to the thread, which is what you want. FWIW, I think there is an i/o bug with threading in the latest release, see bug 2907 http://d.puremagic.com/issues/show_bug.cgi?id=2907 -Steve
May 11 2009
parent reply Brok3n Halo <X2ndshadow hotmail.com> writes:
Thanks for the quick reply but I had the & to begain with and I was getting an
error.  I'm not at my computer right
now so unfortunetly I can't see what it was, but I think it was something along
the lines of thread expecting a
function but that's a delegate. I'll try and find the time to set up the
project on my laptop, and see what the error
was for sure in the next few hours.
May 11 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 May 2009 11:45:34 -0400, Brok3n Halo <X2ndshadow hotmail.com>  
wrote:

 Thanks for the quick reply but I had the & to begain with and I was  
 getting an error.  I'm not at my computer right
 now so unfortunetly I can't see what it was, but I think it was  
 something along the lines of thread expecting a
 function but that's a delegate. I'll try and find the time to set up the  
 project on my laptop, and see what the error
 was for sure in the next few hours.
ah, different issue. Your thread function needs to return void. Thread should accept either a function pointer or a delegate. So it should look like: void testfunc() And kill the return 0. -Steve
May 11 2009
parent reply Brok3n Halo <x2ndshadow hotmail.com> writes:
ah-ha! I was just writing to let you know that's how my project started out and
I
went into this issue, when I decided to try it again and got an error message I
know how to solve.  Probably got it before too, but working off an all-nighter
and
my caffeine hasn't fully kicked in yet. Turns out it's expecting an int
testfunc(), the reason it wasn't working before was I was trying to use a uint
testfunc()

Thanks for the heads up on the I/O issue with threading, the writefln wasn't
producing any output once I got it going and thanks to that I know what the
issue
with that was right away, luckily my actual project doesn't require I/O on a
thread. (I'm writing a multi-threaded raytracer for a class)

Which brings me to my next 2 questions, are dynamic arrays thread safe in D? I
imagine they should be as long as I don't have two threads writing to the same
index at once and the array size doesn't change.  Also is there a thread safe
linked list somewhere?
May 11 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 May 2009 13:46:39 -0400, Brok3n Halo <x2ndshadow hotmail.com>  
wrote:

 ah-ha! I was just writing to let you know that's how my project started  
 out and I
 went into this issue, when I decided to try it again and got an error  
 message I
 know how to solve.  Probably got it before too, but working off an  
 all-nighter and
 my caffeine hasn't fully kicked in yet. Turns out it's expecting an int
 testfunc(), the reason it wasn't working before was I was trying to use  
 a uint
 testfunc()

 Thanks for the heads up on the I/O issue with threading, the writefln  
 wasn't
 producing any output once I got it going and thanks to that I know what  
 the issue
 with that was right away, luckily my actual project doesn't require I/O  
 on a
 thread. (I'm writing a multi-threaded raytracer for a class)

 Which brings me to my next 2 questions, are dynamic arrays thread safe  
 in D? I
 imagine they should be as long as I don't have two threads writing to  
 the same
 index at once and the array size doesn't change.
They are no more thread safe than any other construct. There is no special care taken to ensure writes or reads are thread safe, it is up to you to ensure that.
  Also is there a thread safe
 linked list somewhere?
As far as I know, there are no builtin linked lists in D's standard library. Tango, an alternate standard lib for D1, has linked lists, and dcollections, a collection package I wrote for both D1 phobos and Tango, has linked lists, neither of which has thread safety built in. -Steve
May 11 2009
parent reply Brok3n Halo <x2ndshadow hotmail.com> writes:
I probably should have phrased my question better with the array, what I was
wondering is if it was safe for say two threads to right to the array at the
same
time as long as I'm sure they're not writing to the same index of the array?

Also I'm still getting the "Error: Win32 Exception" with my test code any idea
why? Attached is the latest version.
begin 644 test.d
M;6]D=6QE('1E<W0[#0H-"FEM<&]R="!S=&0N=&AR96%D.PT*:6UP;W)T('-T
M9"YS=&1I;SL-" T*#0II;G0 8V]U;G0 /2`P.PT*#0IV;VED(&UA:6XH*7L-
M" T*"51H<F5A9"!T97-T=&AR96%D.PT*#0H):6YT('1E<W1F=6YC*"E[#0H)
M"7=H:6QE*&-O=6YT/#$P,#`P,#`P*7L-" D)"2LK8V]U;G0[#0H)"7T-" D)
M<F5T=7)N(#`[#0H)?0T*#0H-" ET97-T=&AR96%D(#T ;F5W(%1H<F5A9" F
M=&5S=&9U;F,I.PT*"71E<W1T:')E860N<W1A<G0H*3L-" T*#0H):6YT(&QA
M<W1#;W5N="`](#`[#0H)=VAI;&4H=&5S='1H<F5A9"YG9713=&%T92 I(#T]
M(#$I>PT*"0EI9BAC;W5N="`A/2!L87-T0V]U;G0I>PT*"0D)=W)I=&5F;&XH
M(B5D(BP 8V]U;G0I.PT*"0D);&%S=$-O=6YT(#T 8V]U;G0[#0H)"7T-" E]
%#0H-"GT`
`
end
May 12 2009
next sibling parent "Saaa" <empty needmail.com> writes:
I have never used threads before, but it sounds safe to me as when the 
thread gets thrown of the core and later gets back nothing referred by the 
register has changed.
Again, I am a newbie :)

"Brok3n Halo" <x2ndshadow hotmail.com> wrote in message 
news:gubegl$uup$1 digitalmars.com...
I probably should have phrased my question better with the array, what I 
was
 wondering is if it was safe for say two threads to right to the array at 
 the same
 time as long as I'm sure they're not writing to the same index of the 
 array?

 Also I'm still getting the "Error: Win32 Exception" with my test code any 
 idea
 why? Attached is the latest version.
 
May 12 2009
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 12 May 2009 05:11:49 -0400, Brok3n Halo <x2ndshadow hotmail.com>  
wrote:

 I probably should have phrased my question better with the array, what I  
 was
 wondering is if it was safe for say two threads to right to the array at  
 the same
 time as long as I'm sure they're not writing to the same index of the  
 array?
You can do anything you want without thread safety, but you run the risk of deadlocks or corrupted memory. The problem isn't writing to two different elements of an array, the hard part is *ensuring* that you are writing to two different elements of an array. Multithreading code is tough to write correctly, you may want to read a book on it. D2 promises to be a lot better at helping you ensure this.
 Also I'm still getting the "Error: Win32 Exception" with my test code  
 any idea
 why? Attached is the latest version.
Just realized from reading your code, you are using D1 with Phobos, I have no idea what bugs there are, or how to use threads there, so I can't really help you. I can tell you that your code ported to Tango runs without throwing an exception, code below: import tango.core.Thread; import tango.io.Stdout; int count = 0; void main(){ Thread testthread; void testfunc(){ while(count<10000000){ ++count; } } testthread = new Thread(&testfunc); testthread.start(); int lastCount = 0; while(testthread.isRunning){ if(count != lastCount){ Stdout.formatln("{}", count); lastCount = count; } } } output: 164 16789 23750 29998 36054 4472263 4482283 4488871 4495320 4501356 4507264 4513158 4518987 4524886 4530722 4536557 4542362 4548221 4554051 4559848 4565753 4571592 4577354 4583152 4588942 4594719 4600579 4606375 4612181 4617981 4623686 4629421 -Steve
May 12 2009
parent reply "Saaa" <empty needmail.com> writes:
 I probably should have phrased my question better with the array, what I 
 was
 wondering is if it was safe for say two threads to right to the array at 
 the same
 time as long as I'm sure they're not writing to the same index of the 
 array?
You can do anything you want without thread safety, but you run the risk of deadlocks or corrupted memory.
That is why the question was whether it was safe.
 The problem isn't writing to two different elements of an array,
the hard  part is *ensuring* that you are writing to two different elements 
of an  array.  Multithreading code is tough to write correctly, you may 
want to  read a book on it.
And sometimes it is extremely easy to ensure you are never writing to the same elements.
May 12 2009
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 12 May 2009 10:12:48 -0400, Saaa <empty needmail.com> wrote:

 I probably should have phrased my question better with the array, what  
 I
 was
 wondering is if it was safe for say two threads to right to the array  
 at
 the same
 time as long as I'm sure they're not writing to the same index of the
 array?
You can do anything you want without thread safety, but you run the risk of deadlocks or corrupted memory.
That is why the question was whether it was safe.
If two threads are writing to two different sections of memory, yes it is always safe :) I think that's one of the fundamental premises of threads running anyways. If you couldn't do this, you couldn't have threads.
 The problem isn't writing to two different elements of an array,
 the hard  part is *ensuring* that you are writing to two different  
 elements
 of an  array.  Multithreading code is tough to write correctly, you may
 want to  read a book on it.
And sometimes it is extremely easy to ensure you are never writing to the same elements.
If you are doing anything interesting with an array, this is not the case. Might as well not pass the same array to both threads. Maybe the OP doesn't understand that you can slice up an array quite easily. If you want to ensure two threads don't touch the same memory, don't give both threads access to the same memory. That's the easiest way to ensure thread safety. i.e. I want thread 1 to initialize elements 0, 1, and 2, and thread 2 to initialize elements 3, 4, and 5: thread1 = new ProcessingThread(arrayToInit[0..3]); thread2 = new ProcessingThread(arrayToInit[3..6]); thread1.start(); thread2.start(); Should be completely thread safe. -Steve
May 12 2009
parent reply "Saaa" <empty needmail.com> writes:
 I probably should have phrased my question better with the array, what 
 I
 was
 wondering is if it was safe for say two threads to right to the array 
 at
 the same
 time as long as I'm sure they're not writing to the same index of the
 array?
You can do anything you want without thread safety, but you run the risk of deadlocks or corrupted memory.
That is why the question was whether it was safe.
If two threads are writing to two different sections of memory, yes it is always safe :) I think that's one of the fundamental premises of threads running anyways. If you couldn't do this, you couldn't have threads.
I used to think of an array as one thing, thus making it unsafe to write to it from multiple threads at the same time :) I kind of thought he was asking along this conception.
 The problem isn't writing to two different elements of an array,
 the hard  part is *ensuring* that you are writing to two different 
 elements
 of an  array.  Multithreading code is tough to write correctly, you may
 want to  read a book on it.
And sometimes it is extremely easy to ensure you are never writing to the same elements.
If you are doing anything interesting with an array, this is not the case. Might as well not pass the same array to both threads. Maybe the OP doesn't understand that you can slice up an array quite easily. If you want to ensure two threads don't touch the same memory, don't give both threads access to the same memory. That's the easiest way to ensure thread safety. i.e. I want thread 1 to initialize elements 0, 1, and 2, and thread 2 to initialize elements 3, 4, and 5: thread1 = new ProcessingThread(arrayToInit[0..3]); thread2 = new ProcessingThread(arrayToInit[3..6]); thread1.start(); thread2.start(); Should be completely thread safe. -Steve
Could become more difficult if the distinction would be odd/even elements :P Or creatures on a grid who can only see the cell they stand on :D But yes, slicing is neat!
May 12 2009
parent reply Georg Wrede <georg.wrede iki.fi> writes:
Saaa wrote:
Steven Schveighoffer wrote:
 i.e. I want thread 1 to initialize elements 0, 1, and 2, and thread 2 to 
 initialize elements 3, 4, and 5:

 thread1 = new ProcessingThread(arrayToInit[0..3]);
 thread2 = new ProcessingThread(arrayToInit[3..6]);
 thread1.start();
 thread2.start();

 Should be completely thread safe.
Could become more difficult if the distinction would be odd/even elements :P
Why??? If your threads have no bugs (i.e. the "odd" thread doesn't read or write the "even" elements, and vice versa), then this should be easy!
 Or creatures on a grid who can only see the cell they stand on :D
Then the only thing that has to be thread safe is the code that moves a creature from cell to cell. And, of course, it has to guarantee that no two creatures end up in the same cell.
May 12 2009
parent "Saaa" <empty needmail.com> writes:
"Georg Wrede" <georg.wrede iki.fi> wrote in message 
news:guc6ep$2img$1 digitalmars.com...
 Saaa wrote:
 Steven Schveighoffer wrote:
 i.e. I want thread 1 to initialize elements 0, 1, and 2, and thread 2 to 
 initialize elements 3, 4, and 5:

 thread1 = new ProcessingThread(arrayToInit[0..3]);
 thread2 = new ProcessingThread(arrayToInit[3..6]);
 thread1.start();
 thread2.start();

 Should be completely thread safe.
Could become more difficult if the distinction would be odd/even elements :P
Why??? If your threads have no bugs (i.e. the "odd" thread doesn't read or write the "even" elements, and vice versa), then this should be easy!
 Or creatures on a grid who can only see the cell they stand on :D
Then the only thing that has to be thread safe is the code that moves a creature from cell to cell. And, of course, it has to guarantee that no two creatures end up in the same cell.
I meant slicing would become more difficult.
May 12 2009