MFC多线程开发学习笔记

32位Windows没有每个应用程序只有一个线程的限制。

MFC在CWinThread类中封装了可执行线程,在C++类中封装了事件,互斥和其他Win32线程同步对象。

MFC把线程分为两个类型:UI线程和工作者线程。不同之处在于UI线程具有消息循环而工作者线程没有。


MFC中创建线程最好的方法是调用AfxBeginThread,有两个版本分别对应UI线程和工作者线程。只有在不使用MFC时才可以使用Win32::CreateThread()来创建线程。

创建工作者线程:

CWinThread* pThread = AfxBeginThread(ThreadFunc, &threadInfo);

需要传入一个线程函数和一个包含对线程输入的数据结构的地址。另外还有一个接受4个参数的原型,可以指定线程优先级、堆栈尺寸、产生标志以及安全属性。

创建UI线程:

UI线程是的行为是由从CWinThread派生来的可动态创建的类控制的,类似于CWinApp派生的应用程序。

CWinThread* pThread = AfxBeginThread(RUNTIME_CLASS(CUIThread));

暂停和继续执行线程:

CWinThread::SuspendThread()

CWinThread::REsumeThread()


线程睡眠:

::Sleep(time):在time时间后某时刻醒来。

::Sleep(0): 放弃剩余的时间片

终止线程:

DWORD dwExitCode;
::GetExitCodeThread(pThread->m_hThread, &dwExitCode);

线程同步:


  • 临界区

串行化多个线程共享的链表,简单变量,结构等资源。

CCriticalSection g_cs;   //Global data

....
//Thread A
g_cs.Lock();
....
g_cs.Unlock();


//Thread b
g_cs.Lock();
....
g_cs.Unlock();

Lock()可以接受超时值。


  • 互斥量

可以同步在不同进程上运行的线程。

//Global data
CMutex g_mutex(FALSE, _T("MyMutex"));
....
if(g_mutex(60000))
{
  .....
  g_mutex.Unlock();
}

互斥量与临界区还有一个区别,如果线程锁定了临界区而终止时没有解锁,那么等待临界区空闲的其他线程将无限期阻塞下去。然而,如果锁定互斥量的线程不能在其终止前解除互斥量的锁定,那么系统将认为互斥量被放弃了并自动释放。


  • 事件

一个事件对象不只是操作系统内核中的一个标记,在任何特定时间,时间只能处在两种状态中的一种:引发或者调低。

CEvent::SetEvent();    设置一个事件

CEvent::ResetEvent();   重置一个事件

CEvent::PulseEvent();   设置或重置一个事件

如果事件只触发一个线程,自动重置SetEvent

如果时间触发多个线程,手动重置PulseEvent

CEvent g_event;
...
//Thread A
InitBuffer(&buffer);
g_event.SetEvent();


//THread B
g_event.Lock();

CEvent g_event(FALSE, TRUE);

//Thread A
InitBuffer(&buffer);
g_event.PulseEvent();

//Thread B
g_event.Lock();

//Thread C
g_event.Lock();


  • 信号量

始终保存代表可用资源数量的资源数。

CSemaphore g_semaphore(m, n);
....
g_semaphore.Lock();
....
g_semaphore.Unlock();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值