线程间的通讯机制。
总的说来一共有三种方法:
使用全局变量
使用Windows消息传递机制
使用事件
上面我们说了线程会共享进程的资源,其中全局变量也包括在内,所以线程可以通过使用全局变量来通讯。但是这种办法的明显的缺点是在有多个线程存取同一个全局变量时,必须考虑同步的问题。譬如:有一个有十个成员变量的结构体,其中一个线程在对起赋值时,假设只更新了五个成员变量的值,这时内核的调度线程剥夺其运行权给另一个线程,这样接下来的线程如果想要用该全局结构体变量,它的值就显然不对了。另外多线程的程序也很难调试,尤其这些错误很隐蔽和很难复现时。如果两个线程都是用户界面线程时,用WINDOWS的消息机制来进行线程间的通讯是比较方便的
您所要做的只是自定义一些windows消息(注意不要和windows的预定义的消息冲突),然后在线程之间传递可以了。您可以这样来定义消息,把WM_USER(它的值等于0x0400)当作基数,然后顺序地去加序号,譬如:
WM_MYCUSTOMMSG equ WM_USER+100h
小于WM_USER 的值是Windows系统的保留值,大于该值留给用户来使用。
如果其中有一个线程是工作者线程的话,那就不能用该种方法来进行通讯了,这是因为工作者线程没有消息队列。您应当用下面这种策略来进行工作者线程和用户界面线程之间的通讯:
User interface Thread ------> global variable(s)----> Worker thread
Worker Thread ------> custom window message(s) ----> User interface Thread
稍后我们的例子中将讲解这种通讯办法。
最后的办法是事件对象。您可以把事件对象看作是一种标志。如果事件对象的状态是无信号的话,说明该线程正在睡眠或挂起,在该种状态下系统是不会给该线程分配CPU时间片的。当一个线程的状态转成有信号时,WINDOWS就会唤醒该线程并且让它正常运行。
例子:
您可以下载例子并运行thread1exe,然后激活菜单项"Savage Calculation",然后程序开始执行指令"add eax,eax ",一共执行600,000,000次,您会发现在这个过程当中,用户界面将停止响应,您既不能使用菜单,也不能使用移动窗口。等到计算完成后,会d出一个对话框,关闭掉对话框后窗口才可以和当初一样正常运行了。
为了避免这种不便,我们把计算的工作放入到一个单独的工作者线程中去,而主窗口仅仅响应用户的活动。您可以看到虽然用户界面的反应比平常时慢了,但还是可以工作的。
386
model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windowsinc
include \masm32\include\user32inc
include \masm32\include\kernel32inc
includelib \masm32\lib\user32lib
includelib \masm32\lib\kernel32lib
const
IDM_CREATE_THREAD equ 1
IDM_EXIT equ 2
WM_FINISH equ WM_USER+100h
data
ClassName db "Win32ASMThreadClass",0
AppName db "Win32 ASM MultiThreading Example",0
MenuName db "FirstMenu",0
SuccessString db "The calculation is completed!",0
data
hInstance HINSTANCE
CommandLine LPSTR
hwnd HANDLE
ThreadID DWORD
code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
mov wccbSize,SIZEOF WNDCLASSEX
mov wcstyle, CS_HREDRAW or CS_VREDRAW
mov wclpfnWndProc, OFFSET WndProc
mov wccbClsExtra,NULL
mov wccbWndExtra,NULL
push hInst
pop wchInstance
mov wchbrBackground,COLOR_WINDOW+1
mov wclpszMenuName,OFFSET MenuName
mov wclpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wchIcon,eax
mov wchIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wchCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,300,200,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
BREAK IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
ENDW
mov eax,msgwParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
ELSEIF uMsg==WM_COMMAND
mov eax,wParam
if lParam==0
if ax==IDM_CREATE_THREAD
mov eax,OFFSET ThreadProc
invoke CreateThread,NULL,NULL,eax,\
0,\
ADDR ThreadID
invoke CloseHandle,eax
else
invoke DestroyWindow,hWnd
endif
endif
ELSEIF uMsg==WM_FINISH
invoke MessageBox,NU
以上就是关于举例说明界面线程中的窗口与后台线程间的消息传递方法(MFC)全部的内容,包括:举例说明界面线程中的窗口与后台线程间的消息传递方法(MFC)、、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)