Multithreading in WindowsProgramPreliminary Design
In general, multi-threaded programming is mostly implemented using the MFC class library. How can we design multi-threaded programs without using the MFC? This article will discuss this issue:
Microsoft provides the createthread function for creating a new thread in Windows API. Its syntax is as follows:
Hthread = createthread (& security_attributes, dwstacksize, threadproc, pparam, dwflags, & idthread );
The first parameter is a pointer to the structure of the security_attributes type. Ignore this parameter in Windows 98. In Windows NT, it is set to null. The second parameter is the initial stack size for the new thread. The default value is 0. In any case, Windows dynamically prolongs the size of the stack as needed.
The third parameter of createthread is the indicator pointing to the thread function. Function names are not restricted, but must be declared in the following column:
DWORD winapi threadproc (pvoid pparam );
The fourth parameter of createthread is the parameter passed to threadproc. In this way, the main thread and slave thread can share data.
The fifth parameter of createthread is usually 0, but the flag is create_suincluded when the created thread is not executed immediately. The thread is paused until calling resumethread to resume thread execution. The sixth parameter is an indicator that points to the variable that accepts the execution thread id value.
Most windows programmers prefer to use the Linked Library Function _ beginthread in the C execution period declared in the process. h header file. Its syntax is as follows:
Hthread = _ beginthread (threadproc, uistacksize, pparam );
It is simpler and perfect for most applications. The syntax of this thread function is:
Void _ cdecl threadproc (void * pparam );
When creating a multi-threaded windows program, you must make some modifications in the Project Settings dialog box. Select the "C/C ++" tab and select "code generation" in the "category" drop-down list 」. In the "use run-time library" drop-down list, you can see the "single-threaded" for "release" and the "Debug single-threaded" for debug settings 」. Change these parameters to "multithreaded" and "Debug multithreaded 」. This will change the compiler flag to/mt, which is required by the compiler to compile multi-threaded applications.
The first demo.
/*************************************** ****************
*
* Deom1 --- four threads simultaneously write a file (No parameter)
*
*
**************************************** *******************/
# Include <windows. h>
# Include <process. h>/* _ beginthread, _ endthread */
# Include <iostream>
# Include <fstream>
Using namespace STD;
Ofstream out ("out.txt ");
Void threadfunc1 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread l" <Endl;
}
}
Void threadfunc2 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 2" <Endl;
}
}
Void threadfunc3 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 3" <Endl;
}
}
Void threadfunc4 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 4" <Endl;
}
}
Int main ()
{
Int I = 0;
_ Beginthread (threadfunc1, 0, null );
_ Beginthread (threadfunc2, 0, null );
_ Beginthread (threadfunc3, 0, null );
_ Beginthread (threadfunc4, 0, null );
Sleep (3000 );
Out <"end ";
Return 0;
}
// Demo1 end -----------------------------------------------
second demo.
/************************************ * *****************
* deom2 --- four threads simultaneously write a file (with parameters)
*
***************************** * ****************************/
# include
# include /* _ beginthread, _ endthread */
# include
# include
# include
using namespace STD;
ofstream out ("out.txt");
Void threadfunc1 (pvoid PARAM)
{
While (1)
{
Char * P;
P = (char *) Param;
Sleep (10 );
Out <p <"This was draw by thread l" <Endl;
}
}
Void threadfunc2 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 2" <Endl;
}
}
Void threadfunc3 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 3" <Endl;
}
}
Void threadfunc4 (pvoid PARAM)
{
While (1)
{
Sleep (10 );
Out <"This was draw by thread 4" <Endl;
}
}
Int main ()
{
Char * pstr = "parameter passed successfully ";
_ Beginthread (threadfunc1, 0, pstr );
_ Beginthread (threadfunc2, 0, null );
_ Beginthread (threadfunc3, 0, null );
_ Beginthread (threadfunc4, 0, null );
Sleep (1000 );
Out <"end ";
Return 0;
}
// Demo2 end ------------------------------------------------
Third demo (A Win32 Application)
/*************************************** ****************
*
* Deom3 --- randomly draw a series of rectangles on the screen
*
*
**************************************** *******************/
# Include <windows. h>
# Include <process. h>
Lresult callback wndproc (hwnd, uint, wparam, lparam );
Hwnd;
Int cxclient, cyclient;
Int winapi winmain (hinstance, hinstance hprevinstance,
Pstr szcmdline, int icmdshow)
{
Static tchar szappname [] = text ("rndrctmt ");
MSG;
Wndclass;
Wndclass. Style = cs_hredraw | cs_vredraw;
Wndclass. lpfnwndproc = wndproc;
Wndclass. cbclsextra = 0;
Wndclass. cbwndextra = 0;
Wndclass. hinstance = hinstance;
Wndclass. hicon = loadicon (null, idi_application );
Wndclass. hcursor = loadcursor (null, idc_arrow );
Wndclass. hbrbackground = (hbrush) getstockobject (white_brush );
Wndclass. lpszmenuname = NULL;
Wndclass. lpszclassname = szappname;
If (! Registerclass (& wndclass ))
{
MessageBox (null, text ("this program requires Windows NT! "), Szappname, mb_iconerror );
Return 0;
}
Hwnd = createwindow (szappname, text ("random rectangles "),
Ws_overlappedwindow,
Cw_usedefault, cw_usedefault,
Cw_usedefault, cw_usedefault,
Null, null, hinstance, null );
Showwindow (hwnd, icmdshow );
Updatewindow (hwnd );
While (getmessage (& MSG, null, 0, 0 ))
{
Translatemessage (& MSG );
Dispatchmessage (& MSG );
}
Return msg. wparam;
}
Void thread (pvoid)
{
Hbrush;
HDC;
Int xleft, xright, ytop, ybottom, IRED, igreen, iblue;
While (true)
{
If (cxclient! = 0 | cyclient! = 0)
{
Xleft = rand () % cxclient;
Xright = rand () % cxclient;
Ytop = rand () % cyclient;
Ybottom = rand () % cyclient;
IRED = rand () & 255;
Igreen = rand () & 255;
Iblue = rand () & 255;
HDC = getdc (hwnd );
Hbrush = createsolidbrush (RGB (IRED, igreen, iblue ));
SelectObject (HDC, hbrush );
Rectangle (HDC, min (xleft, xright), min (ytop, ybottom ),
Max (xleft, xright), max (ytop, ybottom ));
Releasedc (hwnd, HDC );
Deleteobject (hbrush );
}
}
}
Lresult callback wndproc (hwnd, uint message, wparam, lparam)
{
Switch (Message)
{
Case wm_create:
_ Beginthread (thread, 0, null );
Return 0;
Case wm_size:
Cxclient = loword (lparam );
Cyclient = hiword (lparam );
Return 0;
Case wm_destroy:
Postquitmessage (0 );
Return 0;
}
Return defwindowproc (hwnd, message, wparam, lparam );
}
// Demo4 end -----------------------------------------------