多线程通常被用于需要长时间运行任务的程序,我们把这种任务称为“大任务”,也就是运行时间超过1/10秒的任务,常见的有Word里的拼写检查,数据库中的文件排序或索引,电子表格的计算,打印,复制的绘制。
下面这个两个程序效果是一样的,主要测试的是:
点击左键,该程序进行一百万次的计算,在计算机过程中,点击右键可以终止,如果不终止,运算完后显示计算时间
代码如下:
#include<windows.h>
#include<math.h>
#include<process.h>
#define REP 1000000
#define STATUS_READY 0
#define STATUS_WORKING 1
#define STATUS_DONE 2
#define WM_CALC_DONE (WM_USER+0)
#define WM_CALC_ABORTED (WM_USER+1)
typedef struct
{
HWND hwnd;
BOOL bContinue;
}PARAMS,*PPARAMS;
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
static TCHAR szAppName[]=TEXT("name");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WindowProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("the program require the window nt"),TEXT("tips"),MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(
szAppName, // registered class name
TEXT("this is title"), // window name
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // horizontal position of window
CW_USEDEFAULT, // vertical position of window
CW_USEDEFAULT, // window width
CW_USEDEFAULT, // window height
NULL, // handle to parent or owner window
NULL, // menu handle or child identifier
hInstance, // handle to application instance
NULL // window-creation data
);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void Thread(PVOID pvoid)
{
double A=1.0;
INT i;
LONG iTime;
volatile PPARAMS pparams;
pparams=(PPARAMS)pvoid;
iTime=GetCurrentTime();
for(i=0;i<REP&&pparams->bContinue;++i)
{
A=(DOUBLE)tan(atan(exp(double(sqrt((double)A*(double)A)))))+1.0;
}
if(i==REP)
{
iTime=GetCurrentTime()-iTime;
SendMessage(pparams->hwnd,WM_CALC_DONE,0,iTime);
}
else
{
SendMessage(pparams->hwnd,WM_CALC_ABORTED,0,0);
}
_endthread();
}
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
static int iStatus;
static long iTime;
static PARAMS params;
static TCHAR *szMessage[]={TEXT("READY"),TEXT("WORKING"),TEXT("%d repeat DONE %d secs")};
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
TCHAR szBuffer[64];
switch(uMsg)
{
case WM_LBUTTONDOWN:
if(iStatus==STATUS_WORKING)
{
MessageBeep(0);
return 0;
}
iStatus=STATUS_WORKING;
params.hwnd=hwnd;
params.bContinue=TRUE;
_beginthread(Thread,0,¶ms);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_RBUTTONDOWN:
params.bContinue=FALSE;
return 0;
case WM_CALC_DONE:
iTime=lParam;
iStatus=STATUS_DONE;
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_CALC_ABORTED:
iStatus=STATUS_READY;
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
wsprintf(szBuffer,szMessage[iStatus],REP,iTime);
DrawText(hdc,szBuffer,-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
#include<windows.h>
#include<math.h>
#include<process.h>
#define REP 1000000
#define STATUS_READY 0
#define STATUS_WORKING 1
#define STATUS_DONE 2
#define WM_CALC_DONE (WM_USER+0)
#define WM_CALC_ABORTED (WM_USER+1)
typedef struct
{
HWND hwnd;
HANDLE hEvent;
BOOL bContinue;
}PARAMS,*PPARAMS;
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
static TCHAR szAppName[]=TEXT("leidemingzi");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);
wndclass.hInstance=hInstance;
wndclass.lpfnWndProc=WindowProc;
wndclass.lpszClassName=szAppName;
wndclass.lpszMenuName=NULL;
wndclass.style=CS_HREDRAW|CS_VREDRAW;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("the program require the window nt"),TEXT("tips"),MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(
szAppName, // registered class name
TEXT("this is title"), // window name
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // horizontal position of window
CW_USEDEFAULT, // vertical position of window
CW_USEDEFAULT, // window width
CW_USEDEFAULT, // window height
NULL, // handle to parent or owner window
NULL, // menu handle or child identifier
hInstance, // handle to application instance
NULL // window-creation data
);
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
VOID Thread(PVOID pvoid)
{
double A=1.0;
int i;
long lTime;
volatile PPARAMS pparams;
pparams=(PPARAMS)pvoid;
while(TRUE)
{
WaitForSingleObject(pparams->hEvent,INFINITE);
lTime=GetCurrentTime();
for(i=0;i<REP&&pparams->bContinue;++i)
{
A=tan(atan(exp(log(sqrt(A*A)))))+1.0;
}
if(i==REP)
{
lTime=GetCurrentTime()-lTime;
PostMessage(pparams->hwnd,WM_CALC_DONE,0,lTime);
}
else
{
PostMessage(pparams->hwnd,WM_CALC_ABORTED,0,0);
}
}
}
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
static HANDLE hEvent;
static int iStatus;
static long lTime;
static PARAMS param;
static TCHAR *szMessage[]={TEXT("READY"),TEXT("WORKING"),TEXT("%d repeats DOWN %d secs")};
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
TCHAR szBuffer[64];
switch(uMsg)
{
case WM_CREATE:
hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
param.hwnd=hwnd;
param.hEvent=hEvent;
param.bContinue=FALSE;
_beginthread(Thread,0,¶m);
return 0;
case WM_LBUTTONDOWN:
if(iStatus==STATUS_WORKING)
{
MessageBeep(0);
return 0;
}
iStatus=STATUS_WORKING;
param.bContinue=TRUE;
SetEvent(hEvent);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_RBUTTONDOWN:
param.bContinue=FALSE;
return 0;
case WM_CALC_DONE:
lTime=lParam;
iStatus=STATUS_DONE;
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_CALC_ABORTED:
iStatus=STATUS_READY;
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
wsprintf(szBuffer,szMessage[iStatus],REP,lTime);
DrawText(hdc,szBuffer,-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}