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