MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出
MFC之AfxbeginThread 線程 創建、掛起、釋放、結束、退出
本文簡單闡述了如何使用一個afxbeginthread創建一個線程(兩種方法,使用默認設置,使用自主設置參數),以及一些如同,掛起,釋放。邊界鎖等操作。
?
①.h文件添加聲明
public:CWinThread *m_pthread;CWinThread *m_pthread2; static UINT __cdecl ?hellothread(LPVOID lparam); //4.掐指算了一下。說是>vs 2005的編譯器定義線程函數都需要添加兩個宏,即UINT _cdeclstatic UINT __cdecl testthread(LPVOID lparam);CCriticalSection g_criticalsection; //邊界鎖,線程間同步用的。 //20190319 updata ? ?如果創建了兩個線程最好使用兩個線程開關。一個開關,好像無法控制兩個線程。BOOL tflag; ?//用作線程開關。
?
//1.線程同步有四種方式,邊界鎖、互斥量(CMutex)、信號燈、CEvent(事件)。不過對于CEvent和邊界鎖感覺能理解。
//http://blog.csdn.net/i_likechard/article/details/77531457 ? ?這個是介紹Cevent在線程中的用法的。
//2.邊界鎖CCriticalSection 和互斥量Cmutex很像,唯一的差別是,CMutex能夠在進程間使用。
//3.網上也有通過UINT hellothread(LPVOID lparam);這種方式直接定義的;不過運行的時候會報錯。
?
②.cpp 文件添加初始化及定義?
//特別注意,線程函數定義的代碼位置一定要位于使用afxbeginthread()之前
在CthreadDlg::CpratiseDlg(CWnd*pParent):CDialogEx(CpratiseDlg::IDD,pParent)函數中,添加如下代碼:將線程開關置為真。我的工程名為thread。
tflag=true;
?
以下為線程函數定義:
UINT __cdecl CthreadDlg::hellothread(LPVOID lparam) //線程1函數定義{ ? ?//CthreadDlg *threadol = new CthreadDlg; ? ? //CthreadDlg *threadol=new CthreadDlg(); ? ? CthreadDlg *threadol=(CthreadDlg*) lparam; ? ? ?//以上3句代碼均可實現將this指針傳遞給threadol對象。通過 "threadol->" 的方式,使得線程1中可以調用主線程的所有函數,全局變量,控件。 ? ?while (threadol->tflag) //通過線程開關控制線程1是否一直開啟。 ? ?{ ? ? ? ? ?//AfxMessageBox("hellothread"); ? ? ? ? //threadol->m_static1.SetWindowTextA("第 1 個線程\n"); ? ? ? ? ?threadol->g_criticalsection.Lock(); //邊界鎖鎖定 ? ? ? ?// 同步鎖中間可添加需要保護的操作代碼,如操作txt文檔讀、看、寫時等。 ? ? ? ?threadol->g_criticalsection.Unlock();//邊界鎖解除 ? ? } ? ?return 0;} UINT __cdecl CthreadDlg::testthread( LPVOID lparam )//線程2函數定義{ ? ?CthreadDlg *threadol = (CthreadDlg*)lparam; ? ? //線程2中寫的比較簡單。可以仿造線程1hellothread進行編寫。 ? ?while(threadol->tflag) ? ?{ ? ? ? ?//do something ? ? ? ?threadol->g_criticalsection.Lock(); //邊界鎖鎖定 ? ? ? ?// 同步鎖中間可添加需要保護的操作代碼,如操作txt文檔讀、看、寫時等。 ? ? ? ?threadol->g_criticalsection.Unlock();//邊界鎖解除 ? ?} ? ?return 0; }
③.cpp中OnInitDialog()函數中添加; //采用了兩種方式來實現線程初始化,都是使用的afxBeginthread();
?tflag=TRUE; //將想成開關置為真。使得可以進行線程循環。 ?//m_pthread = AfxBeginThread(hellothread,(LPVOID)this); ? ?//第一個 線程1 m_pthread1 = AfxBeginThread(hellothread,this,THREAD_PRIORITY_NORMAL,0,0); ?//參數意義:(線程函數名,傳遞當前主對話框指針到線程函數中,普通級別,默認棧大小,自啟動) //第二個 線程2 m_pthread2=AfxBeginThread(testhread,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED); //參數意義:(函數名稱,當前主對話框指針,優先級為“一般”的線程,默認棧大小,創建時掛起)
?
④線程的暫停、開始
//以下操作如同暫停、開始可在某兩個button控件的點擊事件中添加,實現對線程的控制。
SuspendThread(m_pthread2->m_hThread); //掛起第二個線程。“暫停”ResumeThread(m_pthread2->m_hThread); //釋放第二個線程。”播放“
//對于suspendthread和resumethread這兩個函數,其中的參數為句柄。用afxbeginthread創建的線程返回值為一個指針。不過通過這個指針m_pthread2,可以找到m_hThread。
⑤查看線程
調用任務管理器,選擇進程,單擊查看,單擊選擇列,勾選“線程”。即可在任務管理器中查看。
⑥退出關閉一個線程(以下關閉代碼可以添加到某button按鈕下,如ok)
較好的方式:線程函數的return 0;這樣是最安全的。會釋放所有資源。
例如:
void CthreadDlg::OnBnClickedOk(){ ? ?// TODO: 在此添加控件通知處理程序代碼 ? ? tflag=FALSE; ? ? ?//線程開關置為假 ? ?WaitForSingleObject(m_pthread,100); ? ? WaitForSingleObject(m_pthread2,100); ? ? g_criticalsection.Lock(); ? ?//file.Close(); ? ?g_criticalsection.Unlock(); ? ?CDialogEx::OnOK(); ? //關閉對話框}
不正常的方式:exitthread();
例如:
DWORD exitcode2;GetExitCodeThread(m_pthread2,&exitcode2);ExitThread(exitcode2); ??
?//運行了這句話之后,程序直接關閉了。由于我線程創建了兩個。用這句話只能結束一個線程。所以這個東西不安全。不過對于只有一個線程的,在某種情況下使用也是很快。
//2018-7-19 09:25:18 整理了代碼段
原文:https://blog.csdn.net/i_likechard/article/details/51544120?
?
總結
以上是生活随笔為你收集整理的MFC之AfxbeginThread 线程 创建、挂起、释放、结束、退出的全部內容,希望文章能夠幫你解決所遇到的問題。