信号量(CSemaphore)——MFC

一、具体实现:

CSemaphore::CSemaphore(LONG lInitialCount,LONG lMaxCount,LPCTSTR pstrName,

               LPSECURTY_ATTRIBUTES lpsaAttribute):CSyncObject(pstrName)

CSemaphore::~CSemaphore()

_AFXMT_INLINE BOOL CSemaphore::Unlock()

BOOL CSemaphore::Unlock(LONG lCount,LPCTSTR lpPrevCount)

 

二、关于带参数的 Lock()函数的使用(例子)

用一个二维数组模拟三个串行端口

在这个例子用到三个对象:信号量,用于对串行口的资源计数

                        互斥量:修改串行口使用标志数组

                        临界段:用于向屏幕输出结果

先创建一个MFC支持的控制台工程

 

int Buffer[3][5];//模拟串行端口
CSemaphore semaphore(3,3,NULL,NULL);//用于访问串行口的信号量
BOOL Flag[3]={TRUE,TRUE,TURE};
CMutex mutex;//用于保护 Flag[3]的互斥量
CCriticalSection section;//用于访问显示器的临界段
 
一端口读数据后向另一端口写数据的线程ReadAndWriteThread :
 semaphore.Lock();//获串行口 A,此时信号量计数值减1
 mutex.Lock();  //用来修改Flag
  //标记串行口 A 被占用
  mutex.Unlock();
  
  semaphore.Lock();//获串行口 B ,此时信号量计数值减1
  mutex.Lock(); 

  //标记串行口 B 被占用
  mutex.Unlock();
 
  section.Lock();//获得了两个串行口 ,因为要向屏幕输出以观看,所以临界段保护
   //从 A 读数据 
   //向 B 写数据
  section.Unlock();
 
  mutex.Lock();

  //释放对串行口A,B的占用:更改标记

  mutex.Unlock();
 
  semaphore.Unlock(2);//释放两个信号量

写线程:

run=FALSE;

while(!run)  {  Sleep(0); run=semaphore(10); }//由于在主函数要创建多个线程,所以在这采用试探法。

                                            先在一段时间等待资源,若不能,则放弃,过段时间再试探。

                                             如此一直循环,直到获得资源,这样可避免死锁问题。

                                            Sleep(0)意思是放弃分配给该线程的剩余时间片。

  mutex.Lock(); 

  //标记 串行口 被占用
  mutex.Unlock();

 section.Lock();//向串行口写数据 ,因为要向屏幕输出以观看,所以临界段保护
   //向 串行口写数据
  section.Unlock();

 

  mutex.Lock();

  //写完数据后就释放对串行口 的占用:更改标记

  mutex.Unlock();
  semaphore.Unlock();//释放两个信号量

 

主函数:

if(初始化MFC失败)  {//打印失败信息}

else

{

   for(int i=0;i<6;i++)

   ::AfxBeginThread(WriteThread,i+1);//在这创建了6个写线程

   ::AfxBeginThread(ReadAndWriteThread,NULL);

}

 

此程序的运行流程是:

1、首先创建了6个写线程,每个线程都使用信号量,由于信号量的最大计数值是3,所以写了3组Buffer数据;

2、线程写完数据释放了信号量之后,马上被 读写线程获得信号量的计数,于是进行了读写操作。

3、于读写操作只占用了2个信号量,还剩一个信号量继续被写线程所获得。于是又向第三排Buffer写数据;

4、读写操作同时释放了连个信号量后,又马上被写线程获得,于是又向第一、二排Buffer写数据。

 

三、小结

由此可以看出:

1、号量主要是计数的作用,可以很好的控制同一时刻能运行的线程数目。

2、斥量只要控制某一变量或资源在同一时刻不能被多个线程所拥有和操作。

3、临界段主要是在某个区域不能同时运行某个操作。

0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MFC(Microsoft Foundation Classes)是微软开发的一种应用程序框架,它可以简化Windows应用程序的开发。多线程指的是在一个程序中同时运行多个线程,每个线程可以独立执行不同的任务。使用MFC进行多线程编程可以提高程序的性能和响应速度。 在MFC中,我们可以使用CWinThread类来创建和管理线程。首先,我们需要继承CWinThread类并重写其Run函数,在Run函数中编写线程的执行逻辑。然后,通过调用CWinThread的CreateThread函数创建并启动线程。 在多线程编程中,需要特别注意线程之间的同步和互斥。MFC提供了一些同步对象,例如CSemaphore、CCriticalSection等,用于实现线程之间的同步操作。我们可以使用这些同步对象来避免多个线程同时访问共享资源,从而避免发生竞态条件和数据不一致问题。 当然,在多线程编程中,还需要注意避免产生死锁和线程间的资源竞争问题。为了避免死锁,我们可以遵循一些原则,例如按照相同的顺序获取锁、避免嵌套锁等。对于资源竞争问题,我们可以使用互斥锁等同步机制来保证共享资源的正确访问。 总而言之,MFC多线程编程是利用MFC框架进行多线程应用程序的开发。通过继承和重写CWinThread类,我们可以创建和管理多个线程,并使用MFC提供的同步对象来实现线程之间的同步。同时,需要注意避免死锁和资源竞争问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值