www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with receive

reply Bob Cowdery <bob bobcowdery.plus.com> writes:
 Hi

I'm trying out some very simple concurrency tests to make sure I
understand how it operates. However I'm having a few problems. I'm sure
this is just lack of knowledge. I dont know enough to debug these things
on my own yet.

Bob

The test below builds but does not output anything so I assume for some
reason the pattern matching is not working. If I uncomment the line
adding a variant pattern it gives me a compile error.

Error: static assert  "function with arguments (VariantN!(maxSize))
occludes successive function"
But there is no successive function, its the last statement.

Also I tried using a function address instead of a literal but that
gives me a compile error:
Error: static assert  (false || false) is false
From the code it looks its saying that myfunc is not a function.

import std.concurrency, std.stdio, std.variant; int main(char[][] args) { auto low = 0, high = 100; auto tid = spawn(&tfun); foreach(i;low .. high) { tid.send(thisTid,i); } writeln("Exiting"); return 0; } void myfunc(double x) { writeln("Got : ", x); } void tfun() { receive( //&myfunc, (int x) {writeln("Got : ", x);}//, //(Variant any) {writeln("Got : ", any);} ); };
Aug 29 2010
next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
Bob Cowdery wrote:
  Hi
 
 I'm trying out some very simple concurrency tests to make sure I
 understand how it operates. However I'm having a few problems. I'm sure
 this is just lack of knowledge. I dont know enough to debug these things
 on my own yet.
 
 Bob
 
 The test below builds but does not output anything so I assume for some
 reason the pattern matching is not working. If I uncomment the line
 adding a variant pattern it gives me a compile error.
 
 Error: static assert  "function with arguments (VariantN!(maxSize))
 occludes successive function"
 But there is no successive function, its the last statement.
 
 Also I tried using a function address instead of a literal but that
 gives me a compile error:
 Error: static assert  (false || false) is false
From the code it looks its saying that myfunc is not a function.

import std.concurrency, std.stdio, std.variant; int main(char[][] args) { auto low = 0, high = 100; auto tid = spawn(&tfun); foreach(i;low .. high) { tid.send(thisTid,i); } writeln("Exiting"); return 0; } void myfunc(double x) { writeln("Got : ", x); } void tfun() { receive( //&myfunc, (int x) {writeln("Got : ", x);}//, //(Variant any) {writeln("Got : ", any);} ); };

I'm not sure about Variant part yet (never tried it myself), but as for (int x) { /*...*/ } you've got the wrong signature. What you send is (Tid,int), but what you're trying to receive is (int). Try changing your tfun to receive (Tid, int x).
Aug 29 2010
next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
Stanislav Blinov wrote:

 
 I'm not sure about Variant part yet (never tried it myself)

Hmm, after some inspection I can say this is an implementation issue. You'll find that there are cases when what's told in TDPL doesn't work (see recent msg[0] or msg.field[0]? in this group, for example). I' for example, have just found that receive(OwnerTerminated) doesn't work as well. It's just that current dmd and phobos implementations need time to catch up TDPL (I know, things often go in reverse, but with D it's not the case :) )
Aug 29 2010
next sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
Bob Cowdery wrote:
  On 29/08/2010 20:17, Stanislav Blinov wrote:
 Stanislav Blinov wrote:

 I'm not sure about Variant part yet (never tried it myself)

You'll find that there are cases when what's told in TDPL doesn't work (see recent msg[0] or msg.field[0]? in this group, for example). I' for example, have just found that receive(OwnerTerminated) doesn't work as well. It's just that current dmd and phobos implementations need time to catch up TDPL (I know, things often go in reverse, but with D it's not the case :) )

timeout works, not tried that yet. I will probably have explicit thread termination so if OwnerTerminated if a bit broken it's not so important to me but to be able to catch rogue messages and find out what they were is quite key.

Well, I'm not ready to file a bug report yet, but if you're desperate, I *think* this may do the trick for you (assuming you use 2.048): in std/concurrency.d, line 382: Change if ( i < T.length ) to static if ( i < T.length-1 ) This works (for me, at least), even without recompilation of phobos. Mind you, I propose a hack made by hand, and Sean Kelly or other pros here may well find that I'm wrong, so it's at your own risk :)
Aug 29 2010
parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
Stanislav Blinov wrote:
 Bob Cowdery wrote:
  On 29/08/2010 20:17, Stanislav Blinov wrote:
 Stanislav Blinov wrote:

 I'm not sure about Variant part yet (never tried it myself)

You'll find that there are cases when what's told in TDPL doesn't work (see recent msg[0] or msg.field[0]? in this group, for example). I' for example, have just found that receive(OwnerTerminated) doesn't work as well. It's just that current dmd and phobos implementations need time to catch up TDPL (I know, things often go in reverse, but with D it's not the case :) )

timeout works, not tried that yet. I will probably have explicit thread termination so if OwnerTerminated if a bit broken it's not so important to me but to be able to catch rogue messages and find out what they were is quite key.

Well, I'm not ready to file a bug report yet, but if you're desperate, I *think* this may do the trick for you (assuming you use 2.048): in std/concurrency.d, line 382: Change if ( i < T.length ) to static if ( i < T.length-1 ) This works (for me, at least), even without recompilation of phobos. Mind you, I propose a hack made by hand, and Sean Kelly or other pros here may well find that I'm wrong, so it's at your own risk :)

Well, yes, I am wrong, as typeof(T.length) is uint.
Aug 29 2010
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
Stanislav Blinov Wrote:

 Stanislav Blinov wrote:
 
 
 I'm not sure about Variant part yet (never tried it myself)

Hmm, after some inspection I can say this is an implementation issue. You'll find that there are cases when what's told in TDPL doesn't work (see recent msg[0] or msg.field[0]? in this group, for example). I' for example, have just found that receive(OwnerTerminated) doesn't work as well. It's just that current dmd and phobos implementations need time to catch up TDPL (I know, things often go in reverse, but with D it's not the case :) )

Yeah, sorry about that. This is fixed in SVN.
Aug 30 2010
prev sibling next sibling parent Bob Cowdery <bob bobcowdery.plus.com> writes:
 On 29/08/2010 20:17, Stanislav Blinov wrote:
 Stanislav Blinov wrote:

 I'm not sure about Variant part yet (never tried it myself)

Hmm, after some inspection I can say this is an implementation issue. You'll find that there are cases when what's told in TDPL doesn't work (see recent msg[0] or msg.field[0]? in this group, for example). I' for example, have just found that receive(OwnerTerminated) doesn't work as well. It's just that current dmd and phobos implementations need time to catch up TDPL (I know, things often go in reverse, but with D it's not the case :) )

timeout works, not tried that yet. I will probably have explicit thread termination so if OwnerTerminated if a bit broken it's not so important to me but to be able to catch rogue messages and find out what they were is quite key.
Aug 29 2010
prev sibling parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
Bob Cowdery wrote:
  On 29/08/2010 19:17, Stanislav Blinov wrote:
 Bob Cowdery wrote:
  Hi

 I'm trying out some very simple concurrency tests to make sure I
 understand how it operates. However I'm having a few problems. I'm sure
 this is just lack of knowledge. I dont know enough to debug these things
 on my own yet.

 Bob

 The test below builds but does not output anything so I assume for some
 reason the pattern matching is not working. If I uncomment the line
 adding a variant pattern it gives me a compile error.

 Error: static assert  "function with arguments (VariantN!(maxSize))
 occludes successive function"
 But there is no successive function, its the last statement.

 Also I tried using a function address instead of a literal but that
 gives me a compile error:
 Error: static assert  (false || false) is false
 From the code it looks its saying that myfunc is not a function.

int main(char[][] args) { auto low = 0, high = 100; auto tid = spawn(&tfun); foreach(i;low .. high) { tid.send(thisTid,i); } writeln("Exiting"); return 0; } void myfunc(double x) { writeln("Got : ", x); } void tfun() { receive( //&myfunc, (int x) {writeln("Got : ", x);}//, //(Variant any) {writeln("Got : ", any);} ); };

for (int x) { /*...*/ } you've got the wrong signature. What you send is (Tid,int), but what you're trying to receive is (int). Try changing your tfun to receive (Tid, int x).

Thank you. I was following the book blindly without thinking, and the book says (int x) will match 'send(tid, 5)' etc.

Well, there's no misguiding here. It's just that there are two versions of send(), at least in current implementation. One is a free function that gets the destination Tid as its first parameter, the other is Tid's method. So send(tid, 5) is (almost) equivalent to tid.send(5).
Aug 29 2010
prev sibling parent Bob Cowdery <bob bobcowdery.plus.com> writes:
 On 29/08/2010 19:17, Stanislav Blinov wrote:
 Bob Cowdery wrote:
  Hi

 I'm trying out some very simple concurrency tests to make sure I
 understand how it operates. However I'm having a few problems. I'm sure
 this is just lack of knowledge. I dont know enough to debug these things
 on my own yet.

 Bob

 The test below builds but does not output anything so I assume for some
 reason the pattern matching is not working. If I uncomment the line
 adding a variant pattern it gives me a compile error.

 Error: static assert  "function with arguments (VariantN!(maxSize))
 occludes successive function"
 But there is no successive function, its the last statement.

 Also I tried using a function address instead of a literal but that
 gives me a compile error:
 Error: static assert  (false || false) is false
 From the code it looks its saying that myfunc is not a function.

import std.concurrency, std.stdio, std.variant; int main(char[][] args) { auto low = 0, high = 100; auto tid = spawn(&tfun); foreach(i;low .. high) { tid.send(thisTid,i); } writeln("Exiting"); return 0; } void myfunc(double x) { writeln("Got : ", x); } void tfun() { receive( //&myfunc, (int x) {writeln("Got : ", x);}//, //(Variant any) {writeln("Got : ", any);} ); };

I'm not sure about Variant part yet (never tried it myself), but as for (int x) { /*...*/ } you've got the wrong signature. What you send is (Tid,int), but what you're trying to receive is (int). Try changing your tfun to receive (Tid, int x).

Thank you. I was following the book blindly without thinking, and the book says (int x) will match 'send(tid, 5)' etc.
Aug 29 2010