|
-
Mar 12th, 2002, 05:19 AM
#1
Thread Starter
New Member
multithreading concept
dear friends,
i wanna know how to implement multithreading concept in a simp-le vb program or what techniques we need to use.
thanx
-
Mar 19th, 2002, 03:02 AM
#2
Frenzied Member
For implementing Multithreading in VB i've found the Timer control the best. Timer event is automatically generated and you can have as many timer control as you want on one form. and events are asynchronous in nature..But this multithreading would not be structured and you'll have to write a lot of logic and code to implement synchronization of threads.
Another approach is using API to create Threads.CreateThread API Function can be used to create threads and it will require to have a callback function. But I've found this error-prone. So you better don't use it.
-
Mar 19th, 2002, 09:11 AM
#3
PowerPoster
You canot use pure multithreading concepts using API's in VB6. The only option before you is to use ActiveX Exe's for multithreading.
-
Mar 19th, 2002, 03:04 PM
#4
Addicted Member
OK. I've done a significant amount of multithreading in VB. My programs are running very stable.
..........
'amitabh' is quit correct when he says that to do multithreading in VB6, you must use (or include) the ActiveX EXE model. (In VB5, one could use the CreateThread API. This IS NOT true in VB6.)
However, with regards to ActiveX EXE, there are still choices (which is why I mentioned it earlier):
1) You can create a Standard EXE which creates Threads from an external ActiveX EXE (a separate process).
2) You can create a ActiveX EXE that is self contained ... it can create Threads unto itself (it's own process). Additionally, it can also create Threads from another ActiveX EXE (separate process).
..........
'moinkhan' mentioned using a Timer Control to trigger code. This has NOTHING to do with multithreading and DOES NOT allow multiple jobs to be done simultaneously ... If one Timer has triggered and it's associated code is running, the form and the other timers will now be unresponsive until the first Timer's code finishes. So, it's not threaded AT ALL. Yes, you could perform a DoEvents during the first Timer's code and you would have the ILLUSION that the second Timer has triggered code - but in this case your first Timer's code has stopped (at the DoEvents) and will wait there until the second Timer's code is complete. Again, this IS NOT multithreading.
..........
However, even with ActiveX EXE's, a timer may (and likelly will) still come into play - but not the Timer Control. The timer you will be using is the API's SetTimer and KillTimer calls. If you search the web for "VB", "Thread", and "SetTimer" you will find stuff.
..........
Additionally, you can do multithreading in VB6 indirectly using the CreateThread API. In this case, you would get yourself something called PowerBASIC DLL Compiler for Windows. (NO, I DO NOT have ties with the company, but, I posess and endorse their product.) However, it is possible to do everything you want from VB6 - so don't think you need to get this.
-
Mar 19th, 2002, 04:49 PM
#5
Addicted Member
Small point...you can use the CreateThread API when running your app from within VB, but it will not work when compiled.
What is the answer to this question?
-
Mar 20th, 2002, 01:28 AM
#6
Frenzied Member
lot of Thanks Jay Rogozinsky and amitabh!!I got all of your points...Thanx again
If you don't mind please tell me, What role can callback functions play in multithreading? If I decide to create thread thru external ActiveX exe but want each thread to perform different opeartions. can i pass the address of application defined callback function to the ActiveX Exe? or should I use the events???? I perhaps messed up!!! please help
MOIN
-
Mar 20th, 2002, 03:08 AM
#7
PowerPoster
I doubt whether you callback a function from your ActiveX dll. You need to create a standard DLL to use callback functions.
-
Mar 20th, 2002, 04:30 AM
#8
Frenzied Member
There is another non-activeX possibility - write a standard exe that includes a window used for asynchronous communication and launch multiple instances of it.
Each instance will be a process in its own right and if you use PostMessage() to communicate between them then they will be able to run asynchronously.
Worth a try?
HTH,
Duncan
-
Mar 20th, 2002, 02:42 PM
#9
Addicted Member
Yes 'moinkhan', you can use callbacks. However, they are not the exact same type of callbacks typically found in API calls - they are pretty close though. What you would be using from VB is an Automation callback - which, apparently, mainly shines when it is used between Threads of the same Process. Otherwise (if the Threads are in different Processes), a VB Event (as in RaiseEvent), is comparativelly efficient. Look up the use of "Implements" and the Coffee2 project (distributed by MS) - they will help you understand.
You can use Events or Callbacks. You should research as they operate differently. There is no absolute choice.
----------
'MerrionComputin' mentioned creating an non-ActiveX EXE (Standard EXE) which would have a Windows Message Queue (by adding a form or calling the API to create a message Queue). He suggested sending messages to it through PostMessage (which is Asynchronous - meaning the caller would not wait for it to be processed). Well, you could do this. However, you would NOT be creating multiple Threads - you would be creating multiple Processes. The problem here is that you could not call one of these Processes and pass it anything other than basic numbers. For instance, you COULD NOT call it with a memory address (pointer) where you have a bunch of variables. This is because each Process has it's own Protected Memory.
So 'MerrionComputin' would be opening a discussion of cross Process communications, but NOT multi-threading.
Processes take up more resources than Threads. Multi-Threading is powerful because the Threads SHARE the same Process - they can share memory (variables). However, you can share data between Processes in many ways. This would begin a complex discussion which is beyond the scope of the original intent (at this point).
-
Mar 21st, 2002, 03:44 AM
#10
Thread Starter
New Member
Multithreading
Dear friends,
Hi there!
Thanx to u all for your response.
I tried multithreading with CreateThread API but it crashes everytime same as i got from you & other sources.Alongwith it i also tried with ActiveX Dll & tried with CreateThread API but it did not work out.
Can you kindly help me with a small example.
Thanx
-
Mar 21st, 2002, 02:47 PM
#11
Addicted Member
OK.
You CAN NOT use CreateThread in VB6. That's it, that's all.
Do you want to create In-Process Threads or Out-Of-Process Threads? Both can be done in VB. Even a combination. What is your project?
-
Mar 22nd, 2002, 01:52 PM
#12
PowerPoster
Jay:
Maybe you can point me in right direction re In-Process MultiThreads.
I've got an MDIForm which allows multi child forms. These children each contain several PBoxes. I draw graphics in each of the PBOxes contained within each child. This is all done with a realtime datafeed but the actual drawing is done out of my program, the datafeed only provides the raw information which is then manipulated accordingly.
I also have a set of tools which allow the drawing of graphic methods in each PBox using the Mouse Events.
Currently I get a conflict between the two.
I did a sample program where I move the realtime into another process and use SendMessage to flag and update a PBox.
This worked well in my test program.
HOWEVER, implementing it in my original program has created a problem because of the need to not only find the handles to the various PBoxes (Can enumerate to get this), but also the need to access the global arrays which contain the data for the realtime graphics. This causes a major problem because not only are they multidimensional but also large.
SO RELOOKING AT MULTITHREADS. I recognize I need ActiveX, but not sure how I would access they multidimensional arrays using them.
Any suggestions or sample?
-
Mar 22nd, 2002, 03:59 PM
#13
Addicted Member
Sounds like we are working on the same project. LOL.
I am building a RealtTime Database. For me, thats ONE of my issues - pretty much the same as yours. (However, I have additional issues.)
Good ways for you to share data between Threads:
1) A RealTime DB.
2) The Process Memory Heap (HeapCreate and HeapAlloc).
3) A memory mapped file.
Who's your client? ROFL
-
Mar 22nd, 2002, 04:31 PM
#14
PowerPoster
Jay: Have my program done except for posted issue:
Hope some of the following may help you.
My realtime DB is done, but I also keep a certain amount of data in multidimensional arrays for speed. I do a lot of heavy calculations, store the values in the arrays, then when I recalculate the next (x, y) value, just move up the values in the array, add the new value at the end, then repaint the PBox.
Have determined the looping to move the data up in the arrays is
what APPEARS to be causing the conflict. Have tried using DoEvents in loop in hopes it will process any mouse messages but this didn't work.
From my understanding, the mouse ALWAYS takes precedence, so when the mouse is clicked, the Mouse Event is triggered EVEN though your looping and how the OS gets you back to the loop I'm not sure. Sometimes it appears to other times a GPF.
Calling the Heap directly may help in some areas to speed up my code. IF YOU HAVE ANY EXAMPLES ON THIS I WOULD APPRECIATE IT. Have looked into this some, but dealing with multidimensional arrays poses a little bit of problem do to the way bytes are stored but can be overcome.
Have also found that using a For/Next Loop to move values up is much faster than using CopyMemory when dealing with multidimensional arrays.
Have also looked in memory mapped files but could never figure out a way to make them seamless with a database such as Access or SQLServer. Seem to be oriented toward user created binary or random access files. AGAIN IF YOU HAVE A GOOD EXAMPLE USING WITH ACCESS OR SQL SERVER WOULD APPRECIATE LOOKING AT IT. If you need some examples on user created files let me know.
Currently thinking about monitoring mouse messages in loop, if mouse click processing messages than returning. ANY IDEAS OR SUGGESTIONS HERE?
Thanks
David
-
Mar 22nd, 2002, 05:48 PM
#15
Addicted Member
My realtime DB is done, but I also keep a certain amount of data in multidimensional arrays for speed
I am doing something similar.
----------
I do a lot of heavy calculations, store the values in the arrays, then when I recalculate the next (x, y) value, just move up the values in the array, add the new value at the end, then repaint the PBox.
Sounds like you should be using a cyclic buffer methodology and thereby you WONT HAVE TO move large blocks of data around.
----------
From my understanding, the mouse ALWAYS takes precedence, so when the mouse is clicked, the Mouse Event is triggered EVEN though your looping and how the OS gets you back to the loop I'm not sure. Sometimes it appears to other times a GPF.
No -> If you are Looping in your code, your object WILL NOT process pending events - even Mouse Events. The only way, when in a loop, for your object to process pending Events is by using a DoEvents OR perhaps perform some other MessageQueue actions.
DoEvents is dangerous if you do not spend many hours coding for the consequences of using it.
----------
Have also found that using a For/Next Loop to move values up is much faster than using CopyMemory when dealing with multidimensional arrays.
Wow, that's hard to understand. Unless, however, you are doing LOTS of CopyMemory calls. CopyMemory should be MUCH quicker, if done properly. However, I have NOT happened across the need to do it with MultiDimensional arrays. So my comment may be mute. (Again, a cyclic methodology might be better.)
----------
I would have to have a better idea of the issues to assist further. Source code perhaps. I am still not completelly clear on what your issue(s) are.
Currently I get a conflict between the two.
What is the nature of this conflict?
It is sounding like you mean that the Mouse " drawing tools" appear unresponsive while data is being processed. This is exactly why another Thread may be required.
-
Mar 22nd, 2002, 07:24 PM
#16
PowerPoster
Jay:
------------
Quote:
Sounds like you should be using a cyclic buffer methodology and
thereby you WONT HAVE TO move large blocks of data around.
------------
Not sure what you mean by "cyclic buffer methodology"
Familiar with buffers and first-in-first-out, last-in-first-out concepts of arrays or other storage area but not as stated--
Would you please clarify?
------------
Quote:
What is the nature of this conflict?
It is sounding like you mean that the Mouse " drawing tools" appear unresponsive while data is being processed. This is exactly why another Thread may be required
--------------
Yes. That's why I made the original post. But unsure how another thread will work for this. Currently:
1. Use an ActiveX (in my client) to linkto and obtain data from the remote server.
2. Once data is obtained save it to DB.
3. Take data from DB, make necessary calcs and load arrays.
THIS IS WHERE ALL THE LOOPING OCCURS IN INSERTING THE
NEW VALUES .
4. If Mouse Click on PBOX Mouse Event is triggered and IF RealTime Update is triggered by ActiveX then PROBLEMS. Either no update of mouse, or error generated.
SO KEY QUESTION IS:
How do you move click on PBox mouse events call ActiveX WITHOUT PBox still recognizing Mouse is being Moved:
PROBLEMs AS I SEE IT ARE:
1. How to Disable the Mouse linkage to PBox
2. Retaining the handle to the PBox so coordinate values can be obtained from the PBox so drawing (say line) can be drawn,
THIS BEING DONE BY THE ACTIVEX
3. NOT having a conflict between the PBox handle passed to the ActiveX and the same handle being used by the RealTime Update.
Any help would be appreciated
David
-
Mar 23rd, 2002, 06:56 AM
#17
Hyperactive Member
Originally posted by Jay Rogozinsky
You CAN NOT use CreateThread in VB6. That's it, that's all.
You can use it, but it is limited (or is it just my implantation of it?) But you can't use it out of the IDE
-
Mar 23rd, 2002, 06:57 AM
#18
Hyperactive Member
Re: Multithreading
Originally posted by khatri
Dear friends,
Hi there!
Thanx to u all for your response.
I tried multithreading with CreateThread API but it crashes everytime same as i got from you & other sources.Alongwith it i also tried with ActiveX Dll & tried with CreateThread API but it did not work out.
Can you kindly help me with a small example.
Thanx
VB Code:
'Using the CreateThread function in Visual Basic
'is very risky! VB5 is 'kinda' stable, but VB6
'applications will probably crash when you
'use the CreateThread function.
'In a form
'Add a command button to the form
Private Sub Command1_Click()
'KPD-Team 1999
'URL: [url]http://www.allapi.net/[/url]
'After you click this button, try to move the window
'You will see that the AsyncThread-function was executed asynchronously
hThread = CreateThread(ByVal 0&, ByVal 0&, AddressOf AsyncThread, ByVal 0&, ByVal 0&, hThreadID)
CloseHandle hThread
End Sub
Private Sub Form_Unload(Cancel As Integer)
'If the thread is still running, close it
If hThread <> 0 Then TerminateThread hThread, 0
End Sub
'In a module
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public hThread As Long, hThreadID As Long
Public Sub AsyncThread()
'Let this thread sleep for 10 seconds
Sleep 10000
hThread = 0
End Sub
-
Mar 23rd, 2002, 01:02 PM
#19
Addicted Member
Well, if you want to use it 'Hampster', go nuts. I don't see much point in even putting the effort into showing the ACT of calling CreateThread.
DO NOT use CreateThread in VB. It's not stable, not supported, not smart (assuming you know what's going on in VB and the OS).
----------
-
Mar 23rd, 2002, 01:29 PM
#20
Addicted Member
For 'dw85745':
Not sure what you mean by "cyclic buffer methodology"
A cyclic methodology can be used anywhere it is appropriate. It is FIFO in nature. This method is very often used in hardware level serial buffering.
The place where new data arrives is advanced until it reaches the physical end of the buffer, where it wraps around back to the beginning of the physical buffer. In many cases this means you don't have to move data around.
Hope that gives you the idea. It may or may not be right for your application.
Take data from DB, make necessary calcs and load arrays.
This is where you may want another Thread. If there is a significant amount of data, does it 'freeze' the user interface; not allowing them to click?
If Mouse Click on PBOX Mouse Event is triggered and IF RealTime Update is triggered by ActiveX then PROBLEMS. Either no update of mouse, or error generated.
You need some sychronization ...
Perhaps, when the mouse is clicked, tell the ActiveX to stop updating. When it's done, tell the ActiveX to resume updating.
1. How to Disable the Mouse linkage to PBox
You can relocate the click event by using subclassing. (However, you may find that this does not solve your problem.)
3. NOT having a conflict between the PBox handle passed to the ActiveX and the same handle being used by the RealTime Update.
You could use a buffering mechanism. Tell the ActiveX to use a different PBox. If there is no current 'drawing' happening within the visible PBox, BitBlt from the buffer PBox to the visible PBox.
----------
You are facing many of the same issues I am dealing with. I am dealing with them through multiple Threads and the Heap and sychronization objects. Moreover, I have no third party tools - so I can control what happens when. I am getting 300fps from my drawing engine into my PBox.
-
Mar 24th, 2002, 10:12 AM
#21
PowerPoster
Jay:
quote:
--------------------------------------------------------------------------------
"cyclic buffer methodology"
--------------------------------------------------------------------------------
Did a search on planetsourcecode before your post and one sample addressing this. May be somebodies "BUSS" word for a type of buffering. Thanks for explanation.
quote:
----------------
You are facing many of the same issues I am dealing with. I am dealing with them through multiple Threads and the Heap and sychronization objects. Moreover, I have no third party tools - so I can control what happens when. I am getting 300fps from my drawing engine into my PBox.
-----------------
Like yourself not using any third party control other than the ActiveX to link to the Remote Server which is NOT and issue.
I've been trying to crack this for sometime but NO LUCK so far.
The key issues as I see it are:
1. If your in a loop updating whatever, and you click in order to generate a mouse event (position tool for example), a mouse message will be generated. As you drag the mouse (This is where the big problem lies as I see it) mouse messages are generated but since you are in a tight loop they DON"T get processed or processed quickly enough.
2. Possible conflict trying to draw in the same container while dragging the mouse. I don't see this being a big issue as the actual drawing process (MoveTo LineTo for exampel) will be put into the message stream like the mouse.
So as I see it the KEY ISSUE is the loop.
Somehow either the data generated in the loop needs to be buffered and then processed after the drawing, OR the loop halted, messages processed, and loop started again where it left off.
In this regard I've tried DOEvents, various flags stategically placed but no luck.
I've also looked into "State Machines". Concept promoted by Dan Appleman (VBPJ - Winter 1997). Good concept but haven't yet figured out how to make a PRACTICAL application using it.
IF I GET A SOLUTION I'LL LET YOU KNOW. PLEASE DO THE SAME FOR ME.
David
Last edited by dw85745; Mar 24th, 2002 at 10:22 AM.
-
Mar 24th, 2002, 06:13 PM
#22
Addicted Member
Sounds good.
For one thing, when a user clicks in my "PBox", I am going to stop updating it. Why? Because the user clicked to zoom in or something else that relates to the CURRENT DATA. So, I don't want it flying by while he is trying to zoom.
-
Mar 25th, 2002, 04:44 AM
#23
New Member
Please, all of you saying all around the web that VB6 cannot do threading - if you don't know how to do it, it does not mean it cannot be done. It can be done and works absolutely stable. Just remember - VB is all about COM and threads on which you operate must be properly initialized COM threads. If you just use CreateThread API and think that VB code will work on such thread, forget it (will maybe work in IDE but that's another story). It needs much more and what it needs is exactly what VB runtime does to initialize a new thread in multithreaded ActiveX exe.
-
Mar 25th, 2002, 10:29 AM
#24
PowerPoster
Nebojsa:
I think there is general agreement that you can create a separate thead using an ActiveX. Also that VB5 supports API CreateThread while VB6 doesn't.
IMHO while using an ActiveX is viable for a STAND ALONE task OR where a small amount of info is needed to be passed to the ActiveX for processing.
PROBLEMS ARISE where you have large arrays which exist in the MAIN which need to be accessed/manipulated from the ActiveX.
The posts in this thread by Jay and myself hopefully address some of these issues.
If you have a solution, or suggestions please post them.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|