多線程技術在VC中的應用
發表時間:2024-02-22 來源:明輝站整理相關軟件相關文章人氣:
[摘要]山東理工大學 賈永新 肖愛梅 Visual C++ 6.0 自發布以來,以其強大的功能及各種新特性受到廣大編程愛好者的青睞。但是要想成為一個優秀的程序員,寫出真正功能強大、能夠快速響應且實用的程序就必須充分利用一項關鍵技術:多線程。筆者在工作中應用這一技術,開發了一個定時關機的實用程序,在此介紹...
山東理工大學 賈永新 肖愛梅
Visual C++ 6.0 自發布以來,以其強大的功能及各種新特性受到廣大編程愛好者的青睞。但是要想成為一個優秀的程序員,寫出真正功能強大、能夠快速響應且實用的程序就必須充分利用一項關鍵技術:多線程。筆者在工作中應用這一技術,開發了一個定時關機的實用程序,在此介紹給廣大讀者,借此幫助讀者加深對這一技術的理解。
程序的功能
此實用程序的主要功能是實現定時關機,同時也提供了輔助功能:隨時關機、重新啟動、注銷以及動態時鐘。如果設置的時間不對,可以隨時更改。這些功能的具體實現采用了多線程技術。
功能的實現
1.線程的定義
本例中單獨設置了一個線程監視當前時間,在Visual C++中線程的簡單調用語句為:AfxBegin
-Thread(ProcName, param, Priority),第一個參數是線程函數名,param是準備傳送給線程的任意32位值,最后一個是線程的優先級(可用常量表示)。這里先定義一個線程函數:
UINT timeThreadProc(LPVOID pParam) //定義線程,必須照此格式
{
CTime gt; //定義時間變量
int hh,mm,ss; //為存儲時間定義整型變量
do //判斷時間的循環
{
gt=CTime::GetCurrentTime();
//提取當前時間
hh=gt.GetHour(); //分別提取時、分、秒 mm=gt.GetMinute();
ss=gt.GetSecond();
} while ((h!=hh) (m!=mm) (s!=ss));
//判斷當前時間
flag=0; //置狀態標志
ExitWindowsEx(EWX_SHUTDOWN,0);
//關閉計算機
return 0;
}
在上面這個函數中,第一行的格式不能改變,其中的h、m、s是三個全局變量,存儲的是設定的時間(時、分、秒)值。通過循環判斷,如果當前時間滿足設定的條件,則調用MFC的函數ExitWindowsEx(UNIT uFlags, DWORD dwReserved)來關閉計算機。
2.線程的調用
線程的調用方式為:CWinThread * pThread=AfxBeginThread(ProcName,param,Priority),其中pThread是指向該線程的指針。源代碼及說明如下:
void CShutDlg::Onqd()
//設置時間后的響應函數
{
UpdateData(TRUE); //從對話框取值
h=m_xsh; //把時、分、秒值傳給全局變量
m=m_fzh;
s=m_miao;
if (flag==1) {pThread->ResumeThread();}
//通過狀態標志判斷,如果線程已經啟動,則恢復運行
else {
pThread=AfxBeginThread(timeThreadProc,GetSafeHwnd(),THREAD_PRIORITY_NORMAL); //如果線程沒運行,則啟動線程
flag=1;} //把線程狀態標志位置1
m_chsh.EnableWindow(1);
//重設按鈕可用
m_qd.EnableWindow(0);
//設定按鈕不可用
}
點擊“重設”按鈕的響應函數:
void CShutDlg::Onchsh()
{
if(flag==1) //判斷標志位
{
pThread->SuspendThread();
//如果線程已經啟動,則掛起
}
m_chsh.EnableWindow(0);
//重設按鈕不可用
m_qd.EnableWindow(1); //設定按鈕可用
}
在啟動線程的時候,用*pThread保存線程的指針使得我們可以對線程進行掛起(SuspendThread函數)、恢復(ResumeThread函數)等操作,并通過全局變量h、m、s與線程通信,達到定時關機的目的。
3.動態時鐘線程的實現
為了方便定時,在此程序中加入了一個時鐘。原理主要是通過一個定時器(Timer),定時讀取當前時間并按照格式顯示,這里涉及到了VC中的另一個重要函數:OnTimer(UINT nIDEvent)。在程序啟動初始化的時候,加入語句: m_nTimer=SetTimer(1,100,NULL),其中參數100是響應周期(ms)。通過向導加入時間響應函數,代碼如下:
void CShutDlg::OnTimer(UINT nIDEvent) //定時器響應函數
{
CTime gg; //定義時間變量
CString s;
gg=CTime::GetCurrentTime();
//取出當前時間
s.Format(“%02d”,gg.GetSecond());
//定義輸出格式
SetDlgItemText(IDC_miao1,s);
//在程序中顯示時間
s.Format(“%02d”,gg.GetHour());
SetDlgItemText(IDC_xsh1,s);
s.Format(“%02d”,gg.GetMinute());
SetDlgItemText(IDC_fzh1,s);
CDialog::OnTimer(nIDEvent);
}
OnTimer(UINT nIDEvent)是系統函數,它參考初始化時設置的響應周期(100ms)來執行。需要注意的是,如果在程序中設置了Timer,那么在程序結束的時候要加上語句:KillTimer(0),以銷毀定時器對象,否則白白浪費系統資源。
至此一個較為完整的定時器程序完成(其中重啟、注銷功能的實現很簡單,也非本文的主題,故略過),如果再添加幾個線程,即可擴展為一個多功能備忘錄,有興趣的讀者可以加以改進。
小 結
本文中只是簡單地運用了一個線程,控制方式也是簡單地與全局變量通信的方法,在實際應用中還要注意線程同步、線程之間通信、線程與進程之間通信、利用全局變量通信、利用用戶定義消息通信、利用事件通信等等許多重要問題。只有真正掌握了多線程高級編程技術才能寫出實用、優秀的程序。