From: Plum, J. <jp...@ba...> - 2006-02-11 19:32:55
|
Yes, it is correct that it allows the main thread to communicate with = the child threads via the Window Message Queue (though I am workin on a = way to make it last beyond the Window's lifespan). And techinically... no, sending data that way wont work quite yet... but that is the general idea in the end. I plan on moving things to a ThreadsSafe::SendMessage() form in order to = allow lifespan of the children beyond that of the window message queue, = as well as provide and *easy* way of transfering the data to that queue. the format for sending message then would be more along ths lines of: ThreadsSafe::SendMessage(MESSAGE, WPARAM, LPARAM[, DATA]); the reference is a scalar/list/hash/storable object, that will be frozen = by storable and then put on the destination threads's queue, where it = will be sent over to the callback for that threads, in its original form = via thaw. But I think you get the general idea. :) Jason P. -----Original Message----- From: Jeremy White [mailto:jez...@ho...] Sent: Sat 2/11/2006 5:19 AM To: Plum, Jason; per...@li... Subject: RE: [perl-win32-gui-users] Thread Safe Message Passing =20 >Since I was looking for something slightly different than Rob had >provided, I managed to make use of his example (TY Rob) and turn it >around into something more 'famliliar'. Thanks for posting the code - the more feedback and comments, the better = the=20 final solution will be:) >The attached 2 files: >ThreadSafe.pm >Threadsafe_1.pl > >The module is built around the idea that there *had* to be a way to get >messages from the windows thread (main aka tid =3D=3D 0 ) to the child >threads. Would this be the correct usage of your module: #Add this after the window has been created $win->AddButton( -name =3D> 'test', -text =3D> 'test', -pos =3D> [114, 10], -height =3D> 20, -onClick =3D> \&butclick, ); sub butclick { for (1..5) { $win->SendMessage(WM_PIPE1,M_DATA,['some data',$_]); $win->SendMessage(WM_PIPE2,M_DATA,['some data',$_]); } } When the button is clicked, 5 messages are sent to both spawned threads. = Is=20 that correct? Would be correct to say that the essence of your package = is=20 that it allows the main thread to communicate with child threads via the = windows message queue? Cheers, jez. |
From: Plum, J. <jp...@ba...> - 2006-02-12 04:57:38
Attachments:
threadsafe_2.pl
ThreadSafe.pm
|
Hello again all, I've sorted out how to pass the parameters from thread to thread via a = wrapper around SendMessage. I've worked in an allowance for SendMessage (via SendMessageTimeout) to = silently fail if the Window has finished. This is NOT a good way to do = it. Do NOT rely on this. Of course this is far from Production code... = so don't use it for production. Have a look, a pry, and some poking, and tell me what you think :) Jason P. |
From: Plum, J. <jp...@ba...> - 2006-02-12 17:29:57
|
>>I plan on moving things to a ThreadsSafe::SendMessage() form in order = to=20 >>allow lifespan of the children beyond that of the window message = queue, as=20 >>well as provide and *easy* way of transfering the data to that queue. >There is an issue with using the windows queue that you need to be = aware off=20 >(you probably know this anyway, but I'm mentioning it just in case). On = all=20 >versions of windows the queue can't grow beyond a fixed certain size, = and in=20 >versions below XP, the windows queue is relatively small (in xp, the = max=20 >queue size is 10,000). If the queue is full, messages just "disappear". Well, I guess I never stopped to consider a point where the main thread = (the GUI with the window Queue) would ever reach a point where it HAD = 10K entires. I've never managed to get it to have more than 15 at once, = and that was becuase an operation was blocking... The method I've worked out here doesn't leave the messages on the = windows queue, but moves them to its own. This doesn't seem likely to = occur (hitting the limit) but it is a possibility, logicly speaking. >>the format for sending message then would be more along ths lines of: >> >>ThreadsSafe::SendMessage(MESSAGE, WPARAM, LPARAM[, DATA]); >> >>the reference is a scalar/list/hash/storable object, that will be = frozen by=20 >>storable and then put on the destination threads's queue, where it = will be=20 >>sent over to the callback for that threads, in its original form via = thaw. >> >This will work well, I do something similar in another project. >Cheers, >jez. |
From: Jeremy W. <jez...@ho...> - 2006-02-13 08:59:10
|
> >Well, I guess I never stopped to consider a point where the main thread >(the GUI with the window Queue) would ever reach a point where it HAD 10K >entires. I've never managed to get it to have more than 15 at once, and >that was becuase an operation was blocking... > >The method I've worked out here doesn't leave the messages on the windows >queue, but moves them to its own. This doesn't seem likely to occur >(hitting the limit) but it is a possibility, logicly speaking. > Yeah, the likelihood of the message queue becoming full is rare - especially on XP, but saying that Rob and I have exchanged an example which ran fine on XP, but did miss messages on 98 - the example in question was rather convoluted as it sent lots of messages. I've also have an application where the 10k limit can be reached relatively often (several times a day, if the app was running 24/7). This app also sends/receives lots of messages, but the cause of the queue becoming full is due to "slowness" in the machine, typically when an another application starts, or due to a temporary blocking operation (such as opening a dialogue window). In that applications case, an addition thread is spawned (in C) that sits on one end of the message queue and blocks on SendMessage - this ensures that the windows queue only has one message from the internal "queue" thus ensuring that the windows queue never becomes full. Cheers, jez. |
From: Jeremy W. <jez...@ho...> - 2006-02-13 09:54:08
|
>>I've also have an application where the 10k limit can be reached >>relatively often (several times a day, if the app was running 24/7). This >>app also sends/receives lots of messages, but the cause of the queue >>becoming full is due to "slowness" in the machine, typically when an >>another application starts, or due to a temporary blocking operation (such >>as opening a dialogue window). In that applications case, an addition >>thread is spawned (in C) that sits on one end of the message queue and >>blocks on SendMessage - this ensures that the windows queue only has one >>message from the internal "queue" thus ensuring that the windows queue >>never becomes full. > >Is this something that would be a good option for a real GUI threads >implementation? And wouldn't using the option "cure" pre-XP issue, so >maybe it should be turned on by default... to be turned off for performance >only for those apps that know their queues will not suffer overload, or are >willing to allow them to suffer? To be 100% honest I'm not sure. I know this solution works, and as my internal queue is a C structure, the C thread that sits on one end the queue is extremely lightweight. There might be other solutions too. Jason is correct, for most people I doubt that the message queue would become full, especially on XP - but when it does happen it's a right pain to track down the problems it causes. We need to do more testing in real world situations to see how likely this situation arises, especially on boxes pre XP. Cheers, jez. |
From: Plum, J. <jp...@ba...> - 2006-02-13 15:48:47
|
Well, to address this, it is theoretically possible for me to roll my own message queue that is attached to the windows queue for monitored events, and sends messages to the window wherein the window has registered that message with the package. This is an addendum feature to the methods I've been working on to make the threads independent of the window's message queue lifetime. Jason P. -----Original Message----- From: Jeremy White [mailto:jez...@ho...]=20 Sent: Monday, February 13, 2006 4:54 AM To: perl@NevCal.com Cc: Plum, Jason; per...@li... Subject: Re: [perl-win32-gui-users] Thread Safe Message Passing To be 100% honest I'm not sure. I know this solution works, and as my=20 internal queue is a C structure, the C thread that sits on one end the queue=20 is extremely lightweight. There might be other solutions too. Jason is correct, for most people I doubt that the message queue would=20 become full, especially on XP - but when it does happen it's a right pain to=20 track down the problems it causes. We need to do more testing in real world=20 situations to see how likely this situation arises, especially on boxes pre=20 XP. Cheers, jez. |
From: Jeremy W. <jez...@ho...> - 2006-02-12 10:26:42
|
>Yes, it is correct that it allows the main thread to communicate with the >child threads via the Window Message Queue (though I am workin on a way to >make it last beyond the Window's lifespan). > >And techinically... no, sending data that way wont work quite yet... > but that is the general idea in the end. Sounds interesting. >I plan on moving things to a ThreadsSafe::SendMessage() form in order to >allow lifespan of the children beyond that of the window message queue, as >well as provide and *easy* way of transfering the data to that queue. > There is an issue with using the windows queue that you need to be aware off (you probably know this anyway, but I'm mentioning it just in case). On all versions of windows the queue can't grow beyond a fixed certain size, and in versions below XP, the windows queue is relatively small (in xp, the max queue size is 10,000). If the queue is full, messages just "disappear". >the format for sending message then would be more along ths lines of: > >ThreadsSafe::SendMessage(MESSAGE, WPARAM, LPARAM[, DATA]); > >the reference is a scalar/list/hash/storable object, that will be frozen by >storable and then put on the destination threads's queue, where it will be >sent over to the callback for that threads, in its original form via thaw. > This will work well, I do something similar in another project. Cheers, jez. |