MFC多线程互斥锁的使用

您所在的位置:网站首页 mfc互斥锁 MFC多线程互斥锁的使用

MFC多线程互斥锁的使用

2024-04-12 16:51| 来源: 网络整理| 查看: 265

MFC多线程互斥锁的使用

本例演示在MFC中使用多线程。第一部分实现多线程的开启、暂停、继续、注销(见上一篇文章MFC多线程的开启、暂停、继续和注销)。第二部分实现两个线程互斥锁的使用。 演示系统为Win10,平台为VS2017(MFC),主要使用类为CWinThread。

第二部分:

1.在原有基础上(见上一篇文章MFC多线程的开启、暂停、继续和注销)添加一个EDIT控件和一个线程MyThread2。 在这里插入图片描述 2.在ThreadTestDlg.h头文件中添加函数及变量声明:

static UINT MyThread2(LPVOID* pParam);//线程函数 CWinThread *Thread2;//线程2

3.在ThreadTestDlg.cpp实现文件上部中添加变量:

CMutex Mutex;//用于互斥锁

修改文件末尾线程1函数定义:

//线程1函数 UINT CThreadTestDlg::MyThread1(LPVOID* pParam) { CThreadTestDlg *ap1 = (CThreadTestDlg *)pParam;//获取主类指针,在多线程类中使用主类变量需要使用指针ap1-> CSingleLock singleLock(&Mutex); while(1) { if (ThreadKill) { DWORD dwExitCode;//指定线程的退出代码 GetExitCodeThread(ap1->Thread1, &dwExitCode);//获取线程1的退出代码 AfxEndThread(dwExitCode, TRUE);//退出线程 } else { //singleLock.Lock();//没被调用就上锁自己用,已被调用就等着 //if (singleLock.IsLocked()) { n=1; strn.Format(_T("%d"), n); ap1->SetDlgItemText(IDC_EDIT1, strn); Sleep(30); } //singleLock.Unlock();//解锁 } } return 0; }

4.添加线程2函数定义:

UINT CThreadTestDlg::MyThread2(LPVOID* pParam) { CThreadTestDlg *ap2 = (CThreadTestDlg *)pParam;//获取主类指针,在多线程类中使用主类变量需要使用指针ap1-> CSingleLock singleLock(&Mutex); while (1) { if (ThreadKill) { DWORD dwExitCode;//指定线程的退出代码 GetExitCodeThread(ap2->Thread2, &dwExitCode);//获取线程2的退出代码 AfxEndThread(dwExitCode, TRUE);//退出线程 } else { //singleLock.Lock();//没被调用就上锁自己用,已被调用就等着 //if (singleLock.IsLocked()) { n=-1; strn.Format(_T("%d"), n); ap2->SetDlgItemText(IDC_EDIT2, strn); Sleep(30); } //singleLock.Unlock();//解锁 } } return 0; }

5.修改按钮响应函数:

void CThreadTestDlg::OnBnClickedButton1() { n = 0; ThreadKill = FALSE; Thread1 = AfxBeginThread((AFX_THREADPROC)MyThread1, this);//启动线程 Thread2 = AfxBeginThread((AFX_THREADPROC)MyThread2, this);//启动线程 } void CThreadTestDlg::OnBnClickedButton2() { Thread1->SuspendThread(); //暂停线程 Thread2->SuspendThread(); //暂停线程 } void CThreadTestDlg::OnBnClickedButton3() { Thread1->ResumeThread(); //继续线程 Thread2->ResumeThread(); //继续线程 } void CThreadTestDlg::OnBnClickedButton4() { ThreadKill = TRUE;// Thread1->ResumeThread(); //调用继续线程,排除线程处于暂停模式无法注销的情况。若线程处于工作状态,调用此函数无作用。 Thread2->ResumeThread(); //调用继续线程,排除线程处于暂停模式无法注销的情况。若线程处于工作状态,调用此函数无作用。 }

6.编译运行。这是未加互斥锁的情况下,程序中,我们在线程1将n赋值为1并在EDIT1显示;在线程2中将同一个变量n赋值为-1并在EDIT2显示。理论上控件上应分别显示1和-1,但实际上,会出现同时显示1,或同时显示-1或显示-1和1的情况。这是由于线程间同时调用同一变量造成的(严格来讲并不是同时,而是比如线程1赋值为1后还没打印出来就被线程2赋值为-1了,所以造成最后打印出来都是-1,其他情况同理)。 在这里插入图片描述 在这里插入图片描述 7.互斥锁使用。上面修改中其实已经加入了互斥锁的必要说明,只需要把注销掉的代码复原即可实现。实际操作步骤如下: ①添加类变量声明

CMutex Mutex;//用于互斥锁

②在线程中定义互斥锁类变量

CSingleLock singleLock(&Mutex);

③在线程中添加处理代码

singleLock.Lock();//没被调用就上锁自己用,已被调用就等着 if (singleLock.IsLocked()) { //在此添加处理代码 } singleLock.Unlock();//解锁

8.修改后编译运行,可以看到使用互斥锁后,程序按预想的形式运行,EDIT1稳定的显示1,EDIT2稳定的显示-1。 在这里插入图片描述 9.使用互斥锁后,当进入线程1时会先检查变量是否被调用,没有的话就上锁给自己用,待自己用完再解锁,如果变量已经被调用上锁了,那么久等待变量释放。这样在一个线程的运行周期内,其他线程就无法更改变量。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3