
|
Usually you won't get at least one of two things from Windows: multitasking or forking. Real multitasking won't be possible on a machine with but one processor, so the multi-threading you get is the best shot at the bird. At least they say so.
According to the MSDN apps tend to be gentle to each other (as if we didn't know better...). When one doesn't need the CPU, the computing time is handed over by Windows to another thread. If all goes well, each gets it's share.
At the first glance it seems as if there was only one way to have one process yield to another: en-nicing them, so that one has priority over the other. Well, I never saw a programmer who did that without the sword of Damokles (or the boss' wrath) hanging over him/her.
I shall show two possible methods to get Windows to work at least parallel (real multitasking can't be done with only one CPU). By now, there's the "Mama & Baby"-model, but later there will be another: faster and - are you seated? - with shared memory.
Who said, apps can't work parallel? Having each and every do it's work, not waiting for one to finish before you call the other and things like that... I had need of it, since I had to start some polling that took 40 seconds to time out in the worst case. Do a little arithmetics and imagine polling 400 sources at once. Yukk! So, if you have no need to process the results of the first call to make the next, try this model...
Mama & Baby
First imagine two executables: Mama.exe and Baby.exe. Mama.exe doesn't have to interfere with Baby.exe's digestion. She just has to feed it and change the diapers later. Think of both having an interface: IMama in Mama.exe and IBaby in Baby.exe.
IMama provides three functions and some properties. Which properties is up to you; some children can't be given spinach, you know ;)
fGiveBirth Well, fGiveBirth doesn't do much. The function just starts as many Baby.exe as you need and sets the property P_Mama in each IBaby to Me.
This Me is most important, since it carries a pointer to IMama. Wups? Pointers in VB? Well, look further down... I never said there weren't any, hm?
fFeed fFeed is called when IBaby calls fHungry. Here you get the food your Baby.exe needs and answer the needs. Easy, hm?
fChangeDiaper fChangeDiaper is the reaction to IBaby.fWet. It takes away the results of the digestion and gives Baby.exe the room to call for more food.
Baby.exe needs a timer that is disabled at startup and gets enabled by IMama.fGiveBirth. This timer is important for dis-joining the two executables. It is important not to call any functions besides the timer. If you do anything else that might be blocking or timing out, you'll have to wait. The only thing that surely won't block your system is enabling a timer. When the Timer_Event happens, call:
fHungry The first thing to do here is disabling the timer! You wouldn't want the thing to interrupt the digestion, would you? fHungry calls P_Parent.fFeed (P_Parent is IMama, it contains the pointer, you remember?) I use this call to pass over switches or values, just as need be.
fWet Is called when Baby.exe is done with all the functions you want to execute. Like sucking milk, ah, I mean polling ;). The function calls IMama.fChangeDiaper and passes all results. The very last thing you do is re-enabling the timer, so that fHungry can be called again.
P_Mama (who_s_she as Object) As mentioned before, this property contains a pointer to IMama, allthough you wouldn't believe it from the declaration. If you don't mention otherwise, everything is passed ByRef - and what else would that be than a pointer ;) Here you must pass ByRef, since you want to pass a very special IMama.
Keep track of your Babies carefully. What you do here is passing pointers from one to the other like a hot potato. IMama must know of her IBabies, otherwise how would she know which IBaby to call?
And P_Parent contains IMama... This is doubly referencing your objects and unless you clean up, you'll be cluttering your system with not-quite-dead tasks that come up again and again like beans |