Even Better Multithreading with Low Overhead
Posted: 2002-06-01
By: ArchiveBot
Viewed: 105
Filed Under:
No attachments for this post
Theres a code on PSC that says the best stable multithreading in vb6 is done with activex. I say thats the worst advice I've ever heard. This is one of my solutions.
Original Author: Robert Thaggard
Code
Easy multithreading with low overhead - Part 1 Srideep Prasad posted an article on how to do safe multithreading in vb6 with My solution is simple and has low overhead. 1. Create an api dll using visual c++. If you dont know how to program c++, The first step is to make a new Win32 Dynamic-Link Library workspace. Here is LIBRARY MyFile I highlighted the LIBRARY line for a good reason. Make sure whatever you type Public Declare Function
multi instancing. His "solution" required making an activex exe and
making new instances of it for each thread which obviously is very processor
consuming and defeats the very purpose of multithreading. His reason for this
"solution" was "hey, at least theres no more doevents." Give
me a break. I'm dont understand how he code made it to code of the month list.
thats no problem. You can use my template.
2. Make a function that gets the address of the function you want to run in a
seperate thread.
3. From here you can either use the dll as code running in the background to
serve as a "airbag" so you can call CreateThread safely from in the
dll, or you can call the function by yourself in the dll by address. (This is
called a callback routine. Many enumerated functions in the windows api do
this.)
Part 1 of this tutorial will cover how to make a callback routine for your
multithreading.
my code template for an api dll.
#include <windows.h>
// This may be a little confusing to some people.
// All this next line does is specify a vb-safe calling convention
// CALLBACK* says that the variable type is actually a function, in this case a vb function
// THREADED_FUNC is the variable type that the function will be called in the dll. I could have put anything else in here
// typedef BOOL means that the function has a return value of boolean
// (int) means that the function has one paramater and its an integer. You could put as many of these as you need, depending
// on the number of parameters your function takes. ie your function takes an integer and two strings. You would put
// (int, LPCSTR, LPCSTR)
typedef BOOL (CALLBACK* THREADED_FUNC) (int);
// Function prototypes
void FreeProcessor(void);
LONG __declspec(dllexport) WINAPI MakeThread(THREADED_FUNC &pTFunc, int nPassedValue);
// Starting and ending point of the dll, required for every api dll
extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// dll starts processing here
// inital values and processing should go here
}
else if (dwReason == DLL_PROCESS_DETACH)
{
// dll stops processing here
// all clean up code should go here
}
return 1;
}
// MakeThread - Function that calls function by address (This is the callback routine)
// This function accepts a THREADED_FUNC which is actually the address of the threaded function
// It also accepts the parameters your function takes which is an integer for this example. You will need to set the
// number of parameters to match the function you wrote
LONG __declspec(dllexport) WINAPI MakeThread(int nPassedValue, THREADED_FUNC &pTFunc)
{
// try-catch block for error handling
try
{
do
{
// call the function by address and examin return value
if (pTFunc(nPassedValue) == FALSE)
return 1;
FreeProcessor();
} while (true);
}
catch (int) { return 0; }
}
// FreeProcessor function written by Jared Bruni
void FreeProcessor(void)
{
MSG Msg;
while(PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
{
if (Msg.message == WM_QUIT)break;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
The next step is to create a export definitions file for MakeThread. This
is very simple.
DESCRIPTION 'Callback multithreading dll for MyProgram'
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE SINGLE
HEAPSIZE 4096
EXPORTS
MakeThread @1
after LIBRARY is the name of the cpp file that your DllMain is in. For example
if your DllMain is in a file called "BigLousyDll.cpp", then you would
type LIBRARY BigLousyDll
Also make sure that the export definitions file is the same name as the cpp file
your DllMain is in. Like I said, if your DllMain is in a file called "BigLousyDll.cpp",
you would name your export definitions file BigLousyDll.def
Once you compile your dll, it should automatically be registered. I would put it
in your system or system32 folder so you don't have to type a explicit path to
it in your vb file.
MakeThread Lib "MyFile.dll" (lpCallback As
Any, ByVal nInt As
Integer) As Long
Public i As Integer
Public nTimes As Integer
Public Function MyFunction(ByVal nValue As Integer) As Boolean
nTimes = nTimes + 1
If
nTimes > 0 Then
If i
< 20 Then
i = i + 1
End If
MyFunction = True
'Tells dll to keep running through function
Exit Function
Else
i = nValue
MyFunction = True
'Tells dll to keep running through function
Exit Function
End If
MyFunction =
False 'Tells dll to stop
End Function
Sub Main()
If Not MakeThread(AddressOf
MyFunction, 3) Then
MsgBox "Multithreading
error"
Else
MsgBox "Success"
End If
End Sub
If you find this code helpful, vote only if you want to. I dont care if I win
coding contest. I just thought this solution is excellent compared to what
Srideep Prasad posted.
Comments on this post
No comments have been added for this post.
You must be logged in to make a comment.