MFC's AfxbeginThread thread creation, suspension, release, termination, exit

MFC's AfxbeginThread to create a thread


This article briefly explains how to use an afxbeginthread to create a thread (two methods, using default settings, using self-set parameters), and some like, suspend, release. Boundary lock and other operations.

①.h file to add a statement

public:
CWinThread *m_pthread;
CWinThread *m_pthread2;
static UINT __cdecl  hellothread(LPVOID lparam);
 //4. Pinch your fingers and do the math. It is said that the compiler defined thread function of > vs 2005 needs to add two macros, namely UINT _cdecl
static UINT __cdecl testthread(LPVOID lparam);
CCriticalSection g_criticalsection; //Boundary lock, used for synchronization between threads.
BOOL tflag; used as thread switch.

//1. There are four ways of thread synchronization, boundary lock, mutex (CMutex), signal light, CEvent (event). But I can understand CEvent and boundary locks.
//http://blog.csdn.net/i_likechard/article/details/77531457 This is to introduce the usage of Cevent in threads.
//2. The boundary lock CCriticalSection is very similar to the mutex Cmutex, the only difference is that CMutex can be used between processes.
//3. There is also a direct definition through UINT hellothread(LPVOID lparam); in this way; but an error will be reported when running.


②.cpp file adds initialization and definition 

//Special attention, the code location of thread function definition must be located before using afxbeginthread()

In the CthreadDlg::CpratiseDlg(CWnd*pParent):CDialogEx(CpratiseDlg::IDD, pParent) function, add the following code: Set the thread switch to true. My project is named thread.

tflag=true;

the following is the thread function definition:

UINT __cdecl CthreadDlg::hellothread(LPVOID lparam) //Thread 1 function definition
{

//CthreadDlg *threadol = new CthreadDlg;
//CthreadDlg *threadol=new CthreadDlg();
CthreadDlg *threadol=(CthreadDlg*) lparam;  
//The above 3 sentences of code can all realize passing the this pointer to the threadol object. Through the method of "threadol->", thread 1 can call all functions, global variables, and controls of the main thread.

while (threadol->tflag) //Control whether thread 1 is always on through the thread switch.
{  

//AfxMessageBox("hellothread");

//threadol->m_static1.SetWindowTextA("The 1st thread\n");  

threadol->g_criticalsection.Lock(); //Boundary lock lock

// Operation codes that need to be protected can be added in the middle of the synchronization lock, such as when operating txt documents to read, read, and write.

threadol->g_criticalsection.Unlock();//Boundary lock release

}

return 0;

}

UINT __cdecl CthreadDlg::testthread( LPVOID lparam )//Thread 2 function definition

{

CthreadDlg *threadol = (CthreadDlg*)lparam;

 //It is relatively simple to write in thread 2. It can be written by imitating the thread 1hellothread.

while(threadol->tflag)


//do something

threadol->g_criticalsection.Lock(); //Boundary lock lock

// Operation codes that need to be protected can be added in the middle of the synchronization lock, such as when operating txt documents to read, read, and write.

threadol->g_criticalsection.Unlock();//Boundary lock release


return 0;

}


③Added to the OnInitDialog() function in .cpp; //Two ways are used to implement thread initialization, both of which use afxBeginthread();


 tflag=TRUE;


 //Set the imagine switch to true. Makes thread looping possible.


//m_pthread = AfxBeginThread(hellothread,(LPVOID)this);  


//first thread 1


m_pthread1 = AfxBeginThread(hellothread,this,THREAD_PRIORITY_NORMAL,0,0);


//Parameter meaning: (thread function name, pass the current main dialog pointer to the thread function, normal level, default stack size, self-start)


// second thread 2


m_pthread2=AfxBeginThread(testhread,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);


//Parameter meaning: (function name, current main dialog pointer, thread with "normal" priority, default stack size, suspended when created)


④ Thread pause and start


//The following operations can be added to the click event of a button control like pause and start to realize the control of the thread.


SuspendThread(m_pthread2->m_hThread); //Suspend the second thread. "pause"


ResumeThread(m_pthread2->m_hThread); //Release the second thread. "Play"

//For the two functions of suspendthread and resumethread, the parameter is the handle. Threads created with afxbeginthread return a pointer. However, through this pointer m_pthread2, m_hThread can be found.


⑤View Threads


Call Task Manager, select a process, click View, click the selection column, and check "Thread". can be viewed in the task manager.

⑥ Exit to close a thread (the following closing code can be added to a button, such as ok)

A better way: return 0 of the thread function; this is the safest. All resources will be released.

E.g:

void CthreadDlg::OnBnClickedOk()

{
// TODO: Add control notification handler code here
tflag=FALSE;  
//set the thread switch to false
WaitForSingleObject(m_pthread,100);
WaitForSingleObject(m_pthread2,100);

g_criticalsection.Lock();
//file.Close();
g_criticalsection.Unlock();
CDialogEx::OnOK(); //Close the dialog
}
Not the normal way: exitthread();

for example:

DWORD exitcode2;
GetExitCodeThread(m_pthread2,&exitcode2);
ExitThread(exitcode2);   

 //After running this sentence, the program is closed directly. Since my thread created two. Only one thread can be ended with this sentence. So this thing is not safe. However, for only one thread, it is also very fast to use in some cases.


Multithreading example

// global variables
int Thought;
CWinThread* m_pAlarmThread; //Object pointer variable, use this pointer variable to control thread pause, play

UINT Thread_1(LPVOID param);

void CDX_CityDlg::OnBnClickedOk()
{
	// TODO: Add control notification handler code here
	// CDialogEx :: OnOK ();

	Thought=0;

	HWND wnd;
	 

	m_pAlarmThread = AfxBeginThread(Thread_1,this);

	while(Thought==0)
	{

		wnd=::FindWindow(L"Notepad",NULL);

		if(wnd==NULL)
		{
			TRACE(L"Notepad is closed");

			Thought=1;

		}		

	}

return;
}


UINT Thread_1(LPVOID param)
{

	while(Thought==0)
	{
		TRACE(L"Notepad is still open");
		Sleep(500);
	}
	
	TRACE(L"Notepad is still open");

	return 0;
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325932953&siteId=291194637