工作日志(祝勇)10.22

来源:互联网 发布:清朝知乎 编辑:程序博客网 时间:2024/05/16 13:01
 
任务:实现三路视频的任意回放
要求:使用线程控制回放,回放方式可选择
20061022星期日
问题:在两路或三路同时回放同一个文件夹下的BMP图像时,由于两个或三个线程同时访问相同的数据而引发冲突,使线程意外终止。
解决方法:利用MFC提供的同步类和同步访问类。
同步类:CSyncObject, CSemaphore, CMutex, CCriticalSection ,CEvent
同步类用于当访问资源时保证资源的整体性。其中CsyncObject 是其它四个同步类的基类,不直接使用。信号同步类CSemaphore 通常用于当一个应用程序中同时有多个线程访问一个资源(例如,应用程序允许对同一个Document 有多个View)的情况;事件同步类CEvent 通常用于在应用程序访问资源之前应用程序必须等待(比如,在数据写进一个文件之前数据必须从通信端口得到)的情况;而对于互斥同步类CMutex 和临界区同步类CcriticalSection 都是用于保证一个资源一次只能有一个线程访问,二者的不同之处在于前者允许有多个应用程序使用该资源(例如,该资源在一个DLL 当中)而后者则不允许对同一个资源的访问超出进程的范畴,而且使用临界区的方式效率比较高。
同步访问类:CMultiLockCSingleLock
同步访问类用于获得对这些控制资源的访问。CMultiLock CSingleLock 的区别仅在于是需要控制访问多个还是单个资源对象。
本问题可以使用互斥同步类CMutex 信号量同步类CSemaphore和临界区同步类CcriticalSection 中的任意一个解决。
1临界区
临界区是保证在某一个时间只有一个线程可以访问数据的方法。使用它的过程中,需要给各个线程提供一个共享的临界区对象,无论哪个线程占有临界区对象,都可以访问受到保护的数据,这时候其它的线程需要等待,直到该线程释放临界区对象为止,临界区被释放后,另外的线程可以强占这个临界区,以便访问共享的数据。当利用临界区同步时,同一时刻每次只有一个线程可以访问受到保护的数据,这样可以保证程序的稳定性。由于当一个线程访问受到保护的数据的时候,其他线程必须等待,所以同步时耗时也较多。
#include "afxmt.h"
CCriticalSection Section;//声明一个临界区同步类对象
当线程需要访问保护数据时,调用临界区对象的Lock()成员函数;当对保护数据的操作完成之后,调用临界区对象的Unlock()成员函数释放对临界区对象的拥有权,以使另一个线程可以夺取临界区对象并访问受保护的数据。
2互斥
互斥跟临界区很相似,便远比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。通过互斥同步类CMutex来完成线程间的互斥,为了访问一个互斥对象,务必建立一个同步访问类CSingleLockCMultiLock对象,用于访问控制。使用方法:
#include "afxmt.h"
CMutex m_mutex; //声明一个互斥同步类对象
在线程执行函数中声明同步访问类CSingleLock对象
CSingleLock slock(&m_mutex);
如果互斥没有被线程占用,那么当前的调用线程可以成为互斥的占用者。要实现对互斥的访问,就要调用CSingleLock的成员函数Lock(),如果一个线程占用了互斥,那么系统将挂起当前的调用线程,直到这个互斥被释放为止,这时,被挂起的线程将被唤醒并取得对互斥的控制。释放互斥是通过调用CSingleLock的成员函数UnLock()来实现的。
3.信号量
信号量的用法和互斥的用法很相似,不同的是它可以同一时刻允许多个线程访问同一个资源,创建一个信号量需要用Csemaphore类声明一个对象,一旦创建了一个信号量对象,就可以用它来对资源的访问技术。要实现计数处理,先创建一个CsingleLockCmltiLock对象,然后用该对象的Lock()函数减少这个信号量的计数值,Unlock()反之。
本任务中采用临界区同步类。
 
原创粉丝点击