📄 lion-tut-c15.htm
字号:
<BR><B>
hInst,NULL</B> <BR><B> mov hwnd,eax</B>
<BR><B> invoke ShowWindow, hwnd,SW_SHOWNORMAL</B>
<BR><B> invoke UpdateWindow, hwnd</B>
<BR><B> .WHILE TRUE</B>
<BR><B> invoke
GetMessage, ADDR msg,NULL,0,0</B>
<BR><B> .BREAK
.IF (!eax)</B>
<BR><B> invoke
TranslateMessage, ADDR msg</B>
<BR><B> invoke
DispatchMessage, ADDR msg</B> <BR><B> .ENDW</B>
<BR><B> mov eax,msg.wParam</B>
<BR><B> ret</B> <BR><B>WinMain endp</B>
<P><B>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</B>
<BR><B> .IF uMsg==WM_DESTROY</B>
<BR><B> invoke
PostQuitMessage,NULL</B> <BR><B> .ELSEIF uMsg==WM_COMMAND</B>
<BR><B> mov eax,wParam</B>
<BR><B> .if lParam==0</B>
<BR><B> .if
ax==IDM_CREATE_THREAD</B>
<BR><B>
mov eax,OFFSET ThreadProc</B>
<BR><B>
invoke CreateThread,NULL,NULL,eax,\</B>
<BR><B>
0,\</B>
<BR><B>
ADDR ThreadID</B>
<BR><B>
invoke CloseHandle,eax</B>
<BR><B>
.else</B>
<BR><B>
invoke DestroyWindow,hWnd</B>
<BR><B>
.endif</B> <BR><B> .endif</B>
<BR><B> .ELSEIF uMsg==WM_FINISH</B>
<BR><B> invoke MessageBox,NULL,ADDR
SuccessString,ADDR AppName,MB_OK</B> <BR><B> .ELSE</B>
<BR><B> invoke
DefWindowProc,hWnd,uMsg,wParam,lParam</B>
<BR><B> ret</B>
<BR><B> .ENDIF</B> <BR><B>
xor eax,eax</B> <BR><B> ret</B>
<BR><B>WndProc endp</B>
<P><B>ThreadProc PROC USES ecx Param:DWORD</B>
<BR><B> mov ecx,600000000</B>
<BR><B>Loop1:</B> <BR><B> add
eax,eax</B> <BR><B> dec ecx</B>
<BR><B> jz Get_out</B>
<BR><B> jmp Loop1</B>
<BR><B>Get_out:</B> <BR><B> invoke
PostMessage,hwnd,WM_FINISH,NULL,NULL</B>
<BR><B> ret</B> <BR><B>ThreadProc
ENDP</B>
<P><B>end start</B> <BR>
<H3><FONT color=#ff0000>分析:</FONT></H3>主程序的主线程是一个用户界面线程,它有一个普通窗口。用户选择菜单项"Create
Thread",程序就会产生一个线程:
<P><B> .if
ax==IDM_CREATE_THREAD</B>
<BR><B>
mov eax,OFFSET ThreadProc</B>
<BR><B>
invoke CreateThread,NULL,NULL,eax,\</B>
<BR><B>
NULL,0,\</B>
<BR><B>
ADDR ThreadID</B>
<BR><B>
invoke CloseHandle,eax</B> <BR><B> </B>
<BR>上面的代码段产生一个线程,线程的主体代码是函数ThreadProc,该函数和主线程并行运行。在调用成功后,CreateThread函数立即返回,ThreadProc也开始运行。因为我们不再用线程句柄,我们立即关闭它以避免内存泄漏。我们前面讲过关闭句柄不会终止线程的执行,而只是减少起引用计数。
<P><B>ThreadProc PROC USES ecx Param:DWORD</B>
<BR><B> mov ecx,600000000</B>
<BR><B>Loop1:</B> <BR><B> add
eax,eax</B> <BR><B> dec ecx</B>
<BR><B> jz Get_out</B>
<BR><B> jmp Loop1</B>
<BR><B>Get_out:</B> <BR><B> invoke
PostMessage,hwnd,WM_FINISH,NULL,NULL</B>
<BR><B> ret</B> <BR><B>ThreadProc
ENDP</B>
<P>我们看到上面的线程的代码仅仅是做简单的计数工作,因为我们设了一个很大的基数,所以该线程会持续一段您能感觉得到的时间,当结束后它会向主线程发送WM_FINISH消息。WM_FINISH消息是我们自己定义的,它的定义如下:
<UL><B>WM_FINISH equ WM_USER+100h</B>
</UL>WM_USER消息是我们能够使用的最小消息值。<BR>显然我们一看到WM_FINISH,就能从字面上理解该消息的意义。主线程接收到该消息后,会弹出一个对话框告诉用户,计算线程已经结束了。<BR>通过线程之间的通讯,用户可以多次选择"Create
Thread",那样就可以运行多个计算线程了。<BR>本例子中,线程之间的通讯是单向的。如果您想让主线程也能向工作者线程发送消息的话,譬如加入一个菜单项来控制工作者线程的结束,您可以这样做:
<UL>
<LI>add a menu item saying something like "Kill Thread" in the menu
<LI>a global variable which is used as a command flag. TRUE=Stop the thread,
FALSE=continue the thread
<LI>Modify ThreadProc to check the value of the command flag in the loop.
</LI></UL>设立一个全局变量,当线程启动前,我们设置它的值为FALSE,当用户激活了我们加的菜单项时,该值变成TRUE。在线程的代码段ThreadProc中每次减1前,判断该值,如果为TRUE的话线程就结束循环体中的计算并退出线程。
<HR SIZE=1>
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
<BR></DIV><!-- 10:1 文本广告交换 -->
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
<!-- 10:1 文本广告交换 --></DIV>
<HR SIZE=1>
<DIV align=center>翻译:Lxx.阿龙,校对:LuoYunBin's Win32 ASM Page, <A
href="http://asm.yeah.net/">http://asm.yeah.net/</A></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -