>Create(NULL,"UI Thread Window"); wnd->ShowWindow(SW_SHOW); wnd->UpdateWindow(); m_pMainWnd=wnd; return TRUE; } 创建新的用户界面线程 void CUIThreadDlg::OnButton1() { CUIThread* pThread=new CUIThread(); pThread->CreateThread(); } 请注意以下两点: A、在UIThreadDlg.cpp的开头加入语句: #include "UIThread.h" B、把UIThread.h中类CUIThread()的构造函数的特性由 protected 改为 public。 用户界面线程的执行次序与应用程序主线程相同,首先调用用户界面线程类的InitInstance()函数,如果返回TRUE,继续调用线程的Run ()函数,该函数的作用是运行一个标准的消息循环,并且当收到WM_QUIT消息后中断,在消息循环过程中,Run()函数检测到线程空闲时(没有消 息),也将调用OnIdle()函数,最后Run()函数返回,MFC调用ExitInstance()函数清理资源。 你可以创建一个没有界 面而有消息循环的线程,例如:你可以从CWinThread派生一个新类,在InitInstance函数中完成某项任务并返回FALSE,这表示仅执行 InitInstance函数中的任务而不执行消息循环,你可以通过这种方法,完成一个工作者线程的功能。 例程6 MultiThread6 建立一个基于对话框的工程MultiThread6,在对话框IDD_MULTITHREAD6_DIALOG中加入一个按钮IDC_UI_THREAD,标题为“用户界面线程” 右击工程并选中“New Class…”为工程添加基类为CWinThread派生线程类CUIThread。 给工程添加新对话框IDD_UITHREADDLG,标题为“线程对话框”。 为 对话框IDD_UITHREADDLG创建一个基于CDialog的类CUIThreadDlg。使用ClassWizard为CUIThreadDlg 类添加WM_LBUTTONDOWN消息的处理函数OnLButtonDown,如下: void CUIThreadDlg::OnLButtonDown(UINT nFlags, CPoint point) { AfxMessageBox("You Clicked The Left Button!"); CDialog::OnLButtonDown(nFlags, point); } 在UIThread.h中添加 #include "UIThreadDlg.h" 并在CUIThread类中添加protected变量CUIThread m_dlg: class CUIThread : public CWinThread { DECLARE_DYNCREATE(CUIThread) protected: CUIThread(); // protected constructor used by dynamic creation // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CUIThread) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL // Implementation protected: CUIThreadDlg m_dlg; virtual ~CUIThread(); // Generated message map functions //{{AFX_MSG(CUIThread) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP() }; 分别重载InitInstance()函数和ExitInstance()函数: BOOL CUIThread::InitInstance() { m_dlg.Create(IDD_UITHREADDLG); m_dlg.ShowWindow(SW_SHOW); m_pMainWnd=&m_dlg; return TRUE; } int CUIThread::ExitInstance() { m_dlg.DestroyWindow(); return CWinThread::ExitInstance(); } 双击按钮IDC_UI_THREAD,添加消息响应函数: void CMultiThread6Dlg::OnUiThread() { CWinThread *pThread=AfxBeginThread(RUNTIME_CLASS(CUIThread)); } 并在MultiThread6Dlg.cpp的开头添加: #include "UIThread.h" 好了,编译并运行程序吧。每单击一次“用户界面线程”按钮,都会弹出一个线程对话框,在任何一个线程对话框内按下鼠标左键,都会弹出一个消息框。 七、线程间通讯 一般而言,应用程序中的一个次要线程总是为主线程执行特定的任务,这样,主线程和次要线程间必定有一个信息传递的渠道,也就是主线程和次要线程间要进行通信。这种线程间的通信不但是难以避免的,而且在多线程编程中也是复杂和频繁的,下面将进行说明。 使用全局变量进行通信 由 于属于同一个进程的各个线程共享操作系统分配该进程的资源,故解决线程间通信最简单的一种方法是使用全局变量。对于标准类型的全局变量,我们建议使用 volatile 修饰符,它告诉编译器无需对该变量作任何的优化,即无需将它放到一个寄存器中,并且该值可被外部改变。如果线程间所需传递的信息较复杂,我们可以定义一个 结构,通过传递指向该结构的指针进行传递信息。
作者“Data Recovery Laboratory”
|