|
|
|
Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. |
Multithreading Tutorial
Multithreading
Hi, welcome to this little tuturial on Win32 multithreading in
Visual Basic.
For more mutithreading examples download the .zip file which
includes a full sample project and my clsThreading.cls which makes
multithreading much easier.
This tutorial is also included in the .zip file so you don´t
have to read it here.
1. What is multitasking?
On Windows, as it is a 32 bit operating system, more then
one task can run at once. Everybody knows that, you can e.g. run Paint and Windows
Notepad at the same time.
You can switch between these tasks using the buttons in the
taskbar.Well, they do not really run at the same time, because only one
app can control the CPU at once, but Windows switches the processor control
between these apps very fast, so that it seems that they are running at the same
time.
This ability of Windows to handle various tasks at once is
called multitasking.
2. What is multithreading?
But Windows can do even more.
Not only various tasks can run at once, but one task can
create multiple threads, where every thread has its own function. For
example, Windows Explorer can copy a huge file (with the file copy dialog) and,
at the same time, you can still use the TreeView to navigate through the folders.
A normal Visual Basic app is disabled until a task is finished (e.g. open a big
file). In a multithreaded program, you can also click the titlebar and this
won´t stop the program´s activities.
The ability of Windows to allow one app to handle multiple
threads is called multithreading.
3. How can I implement multithreading in my VB program?
To use the cool multithreading in your VB app, you need some
API calls (or my clsThreading.cls which is included in the .zip file) :
The first and most important is the CreateThread
call :
Declare Function CreateThread Lib "kernel32" (ByVal lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
What it does? It creates a new thread in your app. Parameters
:
-
ByVal lpThreadAttributes As Any:
The security attributes for the threads. The normal type is SECURITY_ATTRIBUTES,
but you don´t need this parameter so use ByVal 0&
as value.
-
ByVal dwStackSize As Long:
Tells Windows how much stack memory the thread should have. We don´t need
it, use ByVal 0& for this parameter.
-
ByVal lpStartAddress As Long:
This is the most important parameter. It tells Windows which function the
thread has to execute. To use this parameter, we need the AddressOf
operator which can be used with public functions in public modules
only. So place your threaded function in a module and for the lpStartAddress
parameter use AddressOf YourFunction.
-
ByVal dwCreationFlags As Long:
The creation flags for the thread. To use this parameter, search the CREATE_*
constants in the API Viewer (they are also in clsThreading.cls). One
interesting flag is the CREATE_SUSPENDED flag,
which allows you to create the thread disabled (not running). If you don´t
need this parameter, use ByVal 0&.
-
lpThreadID As Long: This is a ByRef
parameter which represents the ID of the created thread.
The return value of the CreateThread function
is the handle to the created thread. A handle to a thread is like a Window
handle (hWnd). It allows you to take control over the thread. If the CreateThread
function returns 0, it failed to create the thread.
The next important API call is SetThreadPriority
:
Declare Function SetThreadPriority Lib "kernel32" (ByVal hThread As Long, ByVal nPriority As Long) As Long
It sets the priority of a specified thread. Parameters :
-
ByVal hThread As Long: The
handle to the thread. You can use for example the return value of the CreateThread
call.
-
ByVal nPriority As Long: The
new priority of the specified thread. The thread priority has five major
values: THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,
THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL
and THREAD_PRIORITY_HIGHEST which should be
self-explaining. The constants for these values can be found in the API
viewer (and in clsThreading.cls).
To get the actual priority of a thread use the GetThreadPriority
call.
There are two more interesting threading calls, SuspendThread
and ResumeThread :
Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long
Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long
SuspendThread disables a
thread and ResumeThread enables a disabled
thread. Parameters :
The last call, TerminateThread
fully stops a thread. It is important that you stop all threads this way before
closing your application because otherwise, it might crash.
Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Parameters :
4. Thank you
Thank you for reading this tutorial. Now you know the most
common Win32 multithreading calls, you can create, stop, enable, disable threads
and you can change the priority of threads. Did you learn something? If yes,
please vote for me. And excuse me for my bad english because I´m german.
Philipp Weidmann
| |
Download article
Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzipto decompress it.
Virus note:All files are scanned once-a-day by Planet Source Code for viruses,but new viruses come out every day, so no prevention program can catch 100% of them.
FOR YOUR OWN SAFETY, PLEASE: 1)Re-scan downloaded files using your personal virus checker before using it. 2)NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com
|
Terms of Agreement:
By using this article, you agree to the following terms...
1) You may use
this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description. |
Other 2 submission(s) by this author
|
|
|
Report Bad Submission |
|
|
Your Vote! |
See Voting Log |
|
Other User Comments |
1/17/2001 12:17:14 PM:Ultimatum Now HERE is some code that takes the
cake. Finally, no more timers, no more
DoEvents (maybe)
15 * (1/3) globes =)
|
1/17/2001 12:59:15 PM:Fredrik Qvarfort Unfortunately there is a reason why
this code isn't already posted here on
PSC, this is because this code tends to
make VB *very* unstable, so I wouldn't
use it for anything (big).
|
1/17/2001 1:18:03 PM:Simon Price Great tutorial, unstable or not. But if
you have say, 5 threads, and you app
takes one, do you increase the amount
of processing time that your app gets
if you make more threads for yourself?
Like could I make one part of my app
take care of calculations, one part for
graphics, one part for AI etc. and
actually increase the speed of the
program by taking more CPU time?
|
1/17/2001 2:13:10 PM:Venom3249 Hey be nice. This wasn't made for you
programming gurus who already know
everything. PSC is made to help those
who dont know these stuff. So if u
already know multithreading, why did u
even look at this in the first place?
|
1/17/2001 2:27:07 PM:Kunal Johar Wow, ignore the negative comments,
excellent job in your research. This
is a great info for many possible
appliances!
Thanks!
|
1/17/2001 3:24:11 PM:Blake Ignore the guy who didn't have the sack
to post his name with his negative
comment. PSC is a great place to learn
stuff for those who are learning and
it's code like this that helps those
people get a better grasp on what they
are doing. Good job on the tutorial.
|
1/17/2001 4:10:22 PM:Doug Gaede Good job. Note to the guy asking about
CPU time: More threads does not mean
your app gets more CPU time. Different
versions of Windows do it different
ways, but basically they all give an
equal time 'slice' to each thread. If
your functions must happen in a
specific order, threading is not for
you. You won't gain a thing. If your
various functions can happen
concurrently, then yes, you may see an
increase since one function isn't
waiting for another function to finish.
However, the other person is right.
Threading (other than creating separate
ActiveX DLLs or EXEs as VB6 is designed
to do for multi-threading) isn't
something you should do in VB6 for most
production apps. Wait for .NET which
will fully support it, and do it with
stability.
|
1/17/2001 4:13:44 PM:Niall Mooney This is very usefull teaching, thanks
(excellent vote)
|
1/17/2001 5:11:47 PM:Nick Thompson So Cool! Thanks! PSC needs more
advanced tutorials/programs
|
1/17/2001 7:22:29 PM:setraline thanks for the tutorial, i looked on
msdn and other sites for a small
example on how they are used and
couldn't find it, maybe wasn't looking
hard enough, still a simple tutorial to
follow, shows not to be intimidated of
the word multithreading.
|
1/17/2001 7:58:17 PM:Chris Some of us aren't aware that this or
similiar information exists elsewhere,
I appreciate finding it here.
|
1/17/2001 11:51:18 PM:Gil Tried it in VB5. When the app.
closes,
it is still listed in the
TaskList.
WHY? (does not appear to
have been
completely unloaded?)
Also
source code has a typo in the
Property
Let Priority. The argument
should be a
Long.
Great tutorial. Danke!
|
1/17/2001 11:56:53 PM:Gil Tried it on VB5. When the app.
closes,
it is still listed in the
Tasklist.
WHY? Why is any part of the
app still running?
Also in the source
code, there is a typo in the Property
Let Priority. The argument should be a
Long not
Threadpriority.
Great
tutorial. Danke!
|
1/18/2001 2:57:52 AM:Ulli Einer der wenigen Lichtblicke hier.
Prima...
|
1/18/2001 3:06:44 AM:Ulli You should modify your thread class
though such that a thread cannot be
started again once it's running.
|
1/18/2001 4:39:28 AM:Aurilis (LAS) Excellent Work. Poor comments miss the
keywords "looking for some
multithreading stuff and found
nothing"
- This need to be discussed
more. Input ... Input ... need more
Input.
The potential is great.
|
1/18/2001 5:44:40 AM:Cesare Imperiali Great. 5 globes.
|
1/18/2001 5:58:08 AM:Powersoft Programming Finally, a dream come true!! :) Another
5 globes from me...
|
1/18/2001 7:08:50 AM:Jason Singleton This is an example for VB5 only but
there is a great sample program at
www.vbaccelerator.com for programming
multiple threads in VB6.
|
1/18/2001 8:34:07 AM:Brad V great job on submitting this, for
everyone else let's keep the cool sh*t
coming in to PSC. This is something I
was looking into once but never found
anything on it. Again Great Job!!
|
1/18/2001 8:39:26 AM:Jeffrey A. Miller Why is the task still running after I
exit the app?
|
1/18/2001 10:02:03 AM:Gary Lake How do you terminate the app? Clicking
the X only unloads the form but the app
is still running. Ctrl+Alt+Del is the
only way to end it.
Am I missing
something?
|
1/18/2001 1:46:55 PM:Sandeep S Hi
could i pass a value to the
Function or a Sub that the thread is
being created
thanx
|
1/18/2001 2:07:39 PM:Philipp Weidmann Thank you for your feedback! I didn´t
know that this submission will get so
many positie votes...
To the many
peaple who told me about this: I´m
trying to fix the bug that the program
is still runnin with normal exit. I
will update it if it works.
|
1/18/2001 2:19:40 PM:Michael Werren OK it works, but please be careful and
are your shure the program is still
stabileced ? The compiler of VB creates
Multithreading be him self. This is the
reasen why your application can also
crash. But I think good work and you
get best vote......
|
1/19/2001 8:49:17 AM:Philipp Weidmann Hi, finally I fixed the problem that
the program doesn´t exit properly. It
now exits completely. Also a the class
now prevents a thread from being
created more than one time. Worth the
download.
|
1/19/2001 10:35:51 PM:Gary Lake It still doesn't shut down properly in
the design mode.
|
1/20/2001 3:50:42 AM:Philipp Weidmann Well, in the design mode, when you
close the multitheaded app, VB closes,
too. But in a compiled EXE, it will
work. Tip: When running in design mode,
comment the blocks that initialize the
multithreading. You don´t need them to
see if you functions work properly, and
you can´t debug multithreading. When
compiling the EXE, uncomment these
blocks and you have a working
multithreaded EXE.
|
1/20/2001 12:21:00 PM:Mark Withers Just what I was looking for, I needed
this type of code for a setup program.
|
1/20/2001 10:16:14 PM:Shawn Ramsey Right on......... thats a 5/5
|
1/22/2001 2:29:05 AM:RJ Soft of West Tennessee I looked at this code and found it to
be, well, a little unstable. I also
found that clicking and holding the X
down, the graphics jump (speed up then
slow down). I'll continue using
DoEvents in my projects.
|
1/22/2001 10:37:49 AM:Ulli It would be more stable if you used a
switch (set by Terminate btn) to exit
the Do Loops and then use ExitThread to
terminate the threads. According to the
book TerminateThread should only be
used as the last resort to kill a
thread.
|
1/29/2001 6:46:42 AM:Roberto I think your code example is excellent.
I have however the same problem with it
as with my own experiments, when
compiled to native code (VB6), it
crashes when the code uses Sleep calls.
It would be great if sleep calls could
be used so it would only use the
processor when needed.
|
1/31/2001 8:46:52 PM:Tom Pickles very nice code ! 5 Globes from me :)
i'm going to research into converting
it to a raw Bas module though since I
HATE vb's Class modules i might repost
it in .BAS form if i get anywhere ! :)
|
2/14/2001 10:17:17 PM:Eric Sanford MultiThreading is not that hard
just
make an ActiveX exe create a class set
the Instancing = 3 SingleUse and from
another app create more than one of
those classes and each one is in its
own thread with its own globals.
Am I
rong about this? This is what we do at
work and it does create multi threads
of the activeX exe
|
2/17/2001 11:15:38 AM:amorano just one thing to point out.... this is
only for apartment threading. If you
move on over to .NET it has true
multithreading built into VB
|
2/17/2001 2:31:34 PM:Thomas I always thought the real reason for
good multitasking is to start the SAME
routine more than once. And here is
exactly the problem with VB and your
sample. Try to start a thread of the
same subroutine and VB crashes. The
only save way i know of to use threads
is to encapsule them in a ActiveX exe
and that works fine. But your sample is
not bad and is useful for applications
that use only one thread of certain
routines. I think it would be perfect
for serial communications or capi
applications. Nice work.
|
2/17/2001 11:44:07 PM:Andrew GREAT WORK!! A revised version!!
It is
GURUS like Philip Wiedmann that makes
PSC a great VB place!!
Thank you for
your guidance!!
|
2/18/2001 6:30:52 AM:Francesco Finally some cool code that doesn't
crash my VB!
|
2/18/2001 1:52:18 PM:egbert vvvvvery coll but its so unstable i
cant even use it :-( i need to cry
|
2/21/2001 4:34:16 PM:bZenox Men, ignore negative comments, I'm from
Argentina .. and your code Great ...
really we must see more tutoriasl like
yours ... excelent vote ...
|
3/9/2001 4:18:08 AM:Jerry Lau I have started the project in design
time. when i stops it, the Visual Basic
6.0 also shut down or it was not
responding.
i sure my visual studio
6.0 haven't problem.
The same result
was obtain when i use the class in
other project.
Is it the bugs of the
class?
or is the VB 6.0 IDE not
support multithreading ?
|
3/28/2001 11:39:11 PM:ChumpChange WOW... You are GOD!!
P.S. Keep the
planet clean, its not uranus.
|
5/2/2001 8:56:21 AM:Harteveld This is not an itteligent solution: YOU
should try to make a single class
interface which manages the global
memory blocks of different ('virtual')
threads. This means that you should
make a base class which is ATOMIC and
another class which handels the memory
part. This 'memory class' should
handle: Memory Mapped File, Semaphore
and the Muttex. Now you can acces all
'virtual threads' fromout a module.
|
5/22/2001 2:35:06 AM:Nilesh Sawant Hey, Good Job buddy. However I feel
this code is worth only if u want to
execute two different functions in
separate threads..! I tried, however it
seems that this code does not support
executing same function twice in two
different threads.....! Hence to some
extent this is not multithreading, it
is just another flavour of
multithreading (somewhere nearer to
multi-tasking). But anyway, however
whatever is done, deserves
appreciation..!
|
5/29/2001 2:37:10 PM:rob.vanmieghem@zeno.be For all you guys who say it doesn't
work : using the CreateThread
API
call only works well with VB5, NOT in
VB6, it does in the IDE, but not when
it's compiled. This is because
Microsoft changed the threading model
from VB5 to VB6. Multithreading in VB6
can only be done using a trick in an
activex EXE or by implementing a TLB.
|
6/20/2001 5:00:29 AM:richardKeifer Instead of ShowMovingLine,I replaced
with a 'printing to printer'
function.
It crashed VB and does not
get any output on printer.
|
7/1/2001 11:25:01 PM:DEEPU VERY UNSTABLE WITH VB6 !!! TO FIND OUT
WHAT I MEAN REMOVE THE ORIGINAL CODE
FROM THE ShowMovingLine() PROCEDURE AND
ADD THE SIMPLE STATEMENTS BELOW
FOR
I=1 TO 1000
A=I/2
NEXT I
COMPILE
IT AND RUN IT ! WHAT HAPPENS ? A
TERRIFIC EXCEPTION ERROR .... IT
DARESAY THAT THIS WORKS WITH VB 5.0 BUT
WITH VB 6.0 I THINK THE BEST AND MOST
STABLE METHOD IS TO USE ACTIVEX EXEs
|
7/8/2001 12:26:27 PM:Massimo Conti Your Comment to Multithreading
VB:
VERY UNSTABLE WITH VB6 !!! TO
FIND OUT WHAT I MEAN REMOVE THE
ORIGINAL CODE FROM THE ShowMovingLine()
PROCEDURE AND ADD THE SIMPLE STATEMENTS
BELOW FOR I=1 TO 1000 A=I/2 NEXT I
COMPILE IT AND RUN IT ! WHAT HAPPENS ?
A TERRIFIC EXCEPTION ERROR .... IT
DARESAY THAT THIS WORKS WITH VB 5.0 BUT
WITH VB 6.0 I THINK THE BEST AND MOST
STABLE METHOD IS TO USE ACTIVEX
EXEs
Probably yes, ActiveX EXE is
the most stable to use, but however if
you put as the last istruction of the
thread:
frmTest.ThreadControl1.TerminateCurrentT
hread (terminate the current Thread)
you will not recive any EXCEPTION
ERRORS!
|
7/9/2001 3:02:35 AM:Massmo Conti I have seen that this code works fine
only compiled in PCODE.
|
7/21/2001 8:55:37 AM:Lynx Good code however there are some
componets in INet which allow threads
in VB savely and in a very simple way.
I use 'Multithreading for VB' for
example.
|
7/21/2001 9:12:25 AM:Lynx OOPS, (correcting my previous
message)
1. 'savely' -> safely
2.
I've found it on www.snark-soft.com
|
7/26/2001 1:47:08 AM:Hamish I have read quite a few knowledgeable
articles on using the CreateThread
declare in VB and no good things were
said about it. I would refrain from
this method if the app is to be used in
a critical environment.
|
7/30/2001 9:06:16 PM:cksiow Please read this article to find out
why this way of doing multithreading is
not
stable.
http://www.desaware.com/artic
les/threadingL3.htm
|
8/22/2001 6:22:33 PM:Ross First, I wanna say, this is great, I've
been looking for this for a while and
finally found a good example to go by.
PSC has got to be the best programming
site ever. PS. I hate looking in the
microsoft sites for stuff. I can never
find it and it really bugs ya.
Ross
|
9/8/2001 5:02:31 PM:Harry Maugans 1 word. WOW
|
10/22/2001 2:43:47 PM:Pieter de Goeje The class should call the CloseHandle()
function when exiting the thread, or
else the handle to the thread is not
released, and then it still uses memory.
|
10/22/2001 2:49:00 PM:Pieter de Goeje Nice code! Whenever ExitThread() is
called, it should be followed by a call
to CloseHandle(), to invalidate the
handle and release any memory related
to the thread.
|
11/16/2001 4:43:29 AM:Rajinder Verma Good Show...
|
1/2/2002 1:26:12 PM:Aiesi CreateThread allows the programmer to
pass a variable to the worker thread.
How is this executed using VB?
lparameter?
|
1/5/2002 6:18:51 AM:Diptiman Singh Hi...
can it be used for web
downloads??
If yes how to use it
with winsock.
As winsock supports
events.
Won't my program crash ?
|
4/9/2002 3:19:33 PM:Sla Ki Dear Philipp:
Here is the code that
crushes your program:
Public Function
MyCalc()
Dim i As Integer
Dim j As
Integer
For i = 1 To 3
j = i -
1
Next i
End Function
Please call
this function instead of your
ShowAnimation
I really can not
understand why it crushes !!!
Could
you please explaine me ?
|
4/9/2002 3:23:12 PM:sla ki Dear Philipp:
Here is the code that
crushes your program:
Public Function
MyCalc()
Dim i As Integer
Dim j As
Integer
For i = 1 To 3
j = i -
1
Next i
End Function
Please use
this function instead of your
ShowAnimation
I really don't
understand why it crushes.
Could you
please explaine it ?
|
5/29/2002 4:43:22 PM:Joy Im pretty new in
multithrrrrreeading(kind of intimidated
on this word)...but thanks to your code
very neat and easy to understand.
God
Bless
|
6/3/2002 5:34:16 PM:David Rodriguez Amazing! Great job.
|
6/17/2002 3:14:47 PM:test comment
|
6/18/2002 3:01:33 PM:David Fritzsch I've found to possiblities to get this
code running if you compile it to
native code.
This is done by coping
the Thread Local Storage (TLS) from the
VBMainThread into the NewThread.
You
can do it this way:
Pass
TlsGetValue(5) as lpParameter to
CreateThread
The ThreadFunction(
specify with lpStartAddress) must be
change this way
Public Function
ThreadProc(ByVal TLS&)
TlsSetValue
5, TLS
after TlsSetValue you can use
any VBFunctions.
Note that you
share all global variables with the
mainthread.
So if you want to use
objects in the Thread copy global
objectsvariables to a local variables.
Example:
'mod_tmpObj is object you
want to get in the thread
Dim
ThreadObj as Myclass
set
ThreadObj=mod_tmpObj
|
6/24/2002 8:27:26 AM:Joe Why does it only function when i
compile to P-Code and not if i use
Native-Code.
My program hangs also in
the TaskList if it ends although i
terminatetd my thread.
Good
work
Joe
|
6/24/2002 8:31:03 AM: Joe Hi,
Why does it only work if i use
P-Code ? When i use Native Code the
program will crash.
Although i use
terminateprocess my exe-program is
still in the tasklist after ending it.
(VB6)
Several Keywords like App.Path
can't be used in the ThreadFunc. This
will crash the programm too. Why
?
Great work,
Joe
|
6/28/2002 4:25:21 PM:KRussell Hi, this code was very useful. Keep up
the good work.
|
7/1/2002 12:45:50 AM:narayan joshi Dear phillip u have really worked hard
for the multithreading project.
thanks
for such a great help.
looking forward
for ur reply......
|
7/1/2002 8:04:52 AM:Philipp Weidmann Hey!
Thank you all for your
motivating posts! I don't officially
support the multithreading example any
longer because I now explore different
languages but it still makes me happy
to see positive feedback to my
code.
I know it is far from being
perfect and in fact has many bugs (e.g.
only compiles to P-Code etc.) but at
least in some cases it works.
Have
fun!
|
|
Add Your Feedback! |
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.
NOTICE: The author of this article has been kind enough to share it with you. If you have a criticism, please state it politely or it will be deleted.
For feedback not related to this particular article, please click here. |
|