|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
32位汇编语言程序设计中的第12.4节中有个“问题程序”,这个问题程序是用多线程来计数的,这个程序本身要表达的关于线程同步的问题我能理解,但还有一个问题就是,这个程序编译执行后,不能正常退出。我把程序做了一点点的修改,如下(注释的地):
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN equ 1000
DLG_MAIN equ 1000
IDC_COUNTER1 equ 1001
IDC_COUNTER2 equ 1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance dd ?
hWinMain dd ?
hWinCount dd ?
dwThreads dd ?
dwOption dd ?
F_STOP equ 0001h
dwCounter1 dd ?
dwCounter2 dd ?
.const
szStop db '停止计数',0
szStart db '计数',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Counter proc uses ebx esi edi,_lParam
inc dwThreads
invoke SetDlgItemInt,hWinMain,IDC_COUNTER1,dwThreads,FALSE ;加上的代码,用以显示创建的线程数
invoke SetWindowText,hWinCount,addr szStop
and dwOption,not F_STOP
.while ! (dwOption & F_STOP)
inc dwCounter1
mov eax,dwCounter2
inc eax
mov dwCounter2,eax
.endw
dec dwThreads
invoke SetDlgItemInt,hWinMain,IDC_COUNTER2,dwThreads,FALSE ;加上的代码,用以显示最后存留的线程数
invoke SetWindowText,hWinCount,addr szStart
ret
_Counter endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam
local @dwThreadID
mov eax,wMsg
;********************************************************************
.if eax == WM_TIMER
;invoke SetDlgItemInt,hWinMain,IDC_COUNTER1,dwCounter1,FALSE 在代码前加了上注释符
;invoke SetDlgItemInt,hWinMain,IDC_COUNTER2,dwCounter2,FALSE
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if ax == IDOK
.if dwThreads
or dwOption,F_STOP
invoke KillTimer,hWnd,1
.else
mov dwCounter1,0
mov dwCounter2,0
xor ebx,ebx
.while ebx < 10
invoke CreateThread,NULL,0,offset _Counter,NULL,\
NULL,addr @dwThreadID
invoke CloseHandle,eax
inc ebx
.endw
invoke SetTimer,hWnd,1,500,NULL
.endif
.endif
;********************************************************************
.elseif eax == WM_CLOSE
.if ! dwThreads
invoke EndDialog,hWnd,NULL
.endif
;********************************************************************
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinMain
invoke GetDlgItem,hWnd,IDOK
mov hWinCount,eax
;********************************************************************
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,eax,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
修改后编译执行程序,运行结果如图:
有线程在程序中存留,这应该就是程序无法正常退出的原因了。这也是我无法理解的地方 ,为什么会有线程存留?
dwOption的值被修改后,线程不是应该在被按排上时间片后结束的吗?
在课本的后续章节中,用事件对象对程序进行了修改,而我也对修改后的程序又做了如上的一点点变动,扫行结果如下:
多运行几次,也会有线程在程序中存留,但是在这儿程序却可以正常的结束,这又是为什么?
|
|