线程间通信
程序员文章站
2022-06-10 20:50:03
...
线程间通信
全局变量或类的成员变量
1. 全局变量
定义一个全局变量,开启两个线程一个进行自减,一个进行打印,并使用CCriticalSection
类’临界区’进行线程同步。
//CSyncThreadDlg.h
UINT ThreadPoc3(LPVOID pParam);//全局变量 线程函数
UINT ThreadPoc4(LPVOID pParam);
extern UINT g_Num;
public:
CCriticalSection m_cs;//临界区对象
CSyncThreadDlg.h
UINT g_Num = 1000;
void CSyncThreadDlg::OnBnClickedButtonCreateGlobal()
{
CString str;
GetDlgItem(IDC_BUTTON_CREATE_GLOBAL)->GetWindowText(str);
if (_T("创建线程") == str)
{
GetDlgItem(IDC_BUTTON_CREATE_GLOBAL)->SetWindowText(_T("退出线程"));
pGloBalThread3 = AfxBeginThread(ThreadPoc3, NULL);
pGloBalThread4 = AfxBeginThread(ThreadPoc4, this);
//更新UI界面
GetDlgItem(IDC_BUTTON_SUSPEND)->EnableWindow(TRUE);
}
else
{
GetDlgItem(IDC_BUTTON_CREATE_GLOBAL)->SetWindowText(_T("创建线程"));
::TerminateThread(pGloBalThread3->m_hThread, 0);
::TerminateThread(pGloBalThread4->m_hThread, 0);
}
}
UINT ThreadPoc3(LPVOID pParam)
{
while (TRUE)
{
g_Num--;
Sleep(500);
}
return 0;
}
UINT ThreadPoc4(LPVOID pParam)
{
CSyncThreadDlg *pDlg = (CSyncThreadDlg *)pParam;
CString str;
while (TRUE)
{
pDlg->m_cs.Lock();//加锁
str.Format(_T("%d "), g_Num);
pDlg->GetDlgItem(IDC_EDIT_GLOBAL)->SetWindowText(str);
pDlg->m_cs.Unlock();//解锁
OutputDebugString(str);
Sleep(500);
}
return 0;
}
void CSyncThreadDlg::OnBnClickedButtonSuspend()
{
CString str;
GetDlgItem(IDC_BUTTON_SUSPEND)->GetWindowText(str);
if (_T("挂起") == str)
{
GetDlgItem(IDC_BUTTON_SUSPEND)->SetWindowText(_T("唤醒"));
SuspendThread(pGloBalThread3->m_hThread);//挂起线程
SuspendThread(pGloBalThread4->m_hThread);
}
else
{
GetDlgItem(IDC_BUTTON_SUSPEND)->SetWindowText(_T("挂起"));
ResumeThread(pGloBalThread3->m_hThread);//唤醒线程
ResumeThread(pGloBalThread4->m_hThread);
}
}
2. 类的成员变量
定义一个类的成员函数,开启两个线程一个进行自增,一个进行打印
//创建线程与退出线程
void CSyncThreadDlg::OnBnClickedButtonClassCreate()
{
CString str;
GetDlgItem(IDC_BUTTON_CLASS_CREATE)->GetWindowText(str);
if (_T("创建线程") == str)
{
GetDlgItem(IDC_BUTTON_CLASS_CREATE)->SetWindowText(_T("退出线程"));
pClassThread1 = AfxBeginThread(ThreadPoc1, this);
pClassThread2 = AfxBeginThread(ThreadPoc2, this);
m_Num = 0;
//更新UI界面
GetDlgItem(IDC_BUTTON_CLASS_SUPEND)->EnableWindow(TRUE);
}
else
{
GetDlgItem(IDC_BUTTON_CLASS_CREATE)->SetWindowText(_T("创建线程"));
//TerminateThread以异步方式执行,函数返回不代表线程结束,
//线程函数停止执行,位置随机,类对象不会被析构导致内存泄漏
::TerminateThread(pClassThread1->m_hThread, 0);
::TerminateThread(pClassThread2->m_hThread, 0);
}
}
UINT CSyncThreadDlg::ThreadPoc1(LPVOID pParam)
{
CSyncThreadDlg *pDlg = (CSyncThreadDlg *)pParam;
while (TRUE)
{
++(pDlg->m_Num);
Sleep(500);
}
return 0;
}
UINT CSyncThreadDlg::ThreadPoc2(LPVOID pParam)
{
CSyncThreadDlg *pDlg = (CSyncThreadDlg *)pParam;
CString str;
while (TRUE)
{
pDlg->m_cs.Lock();//加锁
str.Format(_T("%d "), pDlg->m_Num);
pDlg->GetDlgItem(IDC_EDIT_CLASS)->SetWindowText(str);
pDlg->m_cs.Unlock();//解锁
OutputDebugString(str);
Sleep(500);
}
return 0;
}
void CSyncThreadDlg::OnBnClickedButtonClassSupend()
{
CString str;
GetDlgItem(IDC_BUTTON_CLASS_SUPEND)->GetWindowText(str);
if (_T("挂起") == str)
{
GetDlgItem(IDC_BUTTON_CLASS_SUPEND)->SetWindowText(_T("唤醒"));
SuspendThread(pClassThread1->m_hThread);//挂起线程
SuspendThread(pClassThread2->m_hThread);
}
else
{
GetDlgItem(IDC_BUTTON_CLASS_SUPEND)->SetWindowText(_T("挂起"));
ResumeThread(pClassThread1->m_hThread);//唤醒线程
ResumeThread(pClassThread2->m_hThread);
}
}
发消息方式
该方式需要自定义消息和绑定,然后一个线程进行消息的发送,而另一个线程不停的接收自定义的的消息,一接收到立马执行。
//方式三:使用创建发消息的方式进行通信
void CSyncThreadDlg::OnBnClickedButtonSendMsgCreate()
{
CWinThread *pThreadPrint = AfxBeginThread(ThreadPrintProc, this);//输出打印线程
CWinThread *pThreadWrite = AfxBeginThread(ThreadWriteProc, (LPVOID)pThreadPrint->m_nThreadID);
}
#define MY_THREAD_MSG (WM_USER+100) //自定义的消息
UINT CSyncThreadDlg::ThreadWriteProc(LPVOID pParam)
{
UINT nCount = 0;
DWORD dwThreadReadID = (DWORD)pParam;//线程ID号
while (true)
{
//线程ID号 自动消息ID 消息参数
PostThreadMessage(dwThreadReadID, MY_THREAD_MSG, nCount++, NULL);
Sleep(500);
}
return 0;
}
//接收消息线程
UINT CSyncThreadDlg::ThreadPrintProc(LPVOID pParam)
{
CSyncThreadDlg *pDlg = (CSyncThreadDlg*)pParam;
MSG msg = { 0 };
while (GetMessage(&msg,0,0,0))
{
switch (msg.message)
{
case MY_THREAD_MSG:
{
pDlg->m_cs.Lock();//加锁
UINT nCount = (int)msg.wParam;
CString str;
str.Format(_T("%d "), nCount);
pDlg->GetDlgItem(IDC_EDIT_SENDMESSAGE)->SetWindowText(str);
pDlg->m_cs.Unlock();//解锁
OutputDebugString(str);
Sleep(500);
}
break;
default:
break;
}
}
return 0;
}