软件测试

收藏 / 订阅

用单例模式解决临界区(CRITICAL_SECTION)的使用问题

  一、前言

  最近,在项目中涉及到多线程访问临界资源的问题。为了保护临界资源,可以是使用互斥量或者是使用临界区。由于,我不需要在多进程中同步,又为了效率的考量,所以选择了使用临界区的方式。但是,在使用临界区的时候,发现了一个类是鸡生蛋蛋生鸡的问题。现将问题和自己的解决方法记录如下,如有不对之处,还请指教。

  二、出现的问题

  在项目的开发过程中,需要把视屏流输出成磁盘的文件,有时候可能有多路视频流同时需要输出到各自的文件中去。对于不同路的视频需要进行分类,不同路的视频存储在不同的目录下。于是在初始化输出文件的时候,需要设置当前目录。有多路视频的时候,每一个都需要在初始化的时候设置当前目录,于是设置的当前目录就是临界资源了。

  下面,是我的输出视频流文件的类:

1 class CAVIFile

2 {

3 public:

4 CAVIFile();

5

6 HRESULT OpenFile(const string& strFileName, const string& strDirectoryPath)

7 {

8 // ....

9 SetCurrentDirectory(strDirectoryPath.c_str());

10 // ...

11 }

12

13 HRESULT WriteVideo(LPVOID lpBuffer, LONG cbBuffer); // 写入视频数据

14 HRESULT WriteAudio(LPVOID lpBuffer, LONG cbBuffer); // 写入获取到的音频数据

15 void CloseFile();

16

17 private:

18 // 一些与本内容无关的成员变量

19 // ...

20 };

  可以看出,如果多个线程同时,进行多路视频的输出时,都调用OpenFile()初始化输出文件,当第一个线程设置当前目录,还没有初始化完成的时候,第二个线程也调用了OpenFile()设置了不同的当前目录,那么第一个线程的初始化的当前目录就会被覆盖。此时就需要加锁,这里选择了临界区。由于不同CAVIFile对象由不同的线程执行,而不同的CAVIFile对象设置当前目录,都会相互影响,所以不同的CAVIFile对象需要公用一个临界区。所以声明临界区为静态成员。

  下面是加上临界区之后的代码:

1 class CAVIFile

2 {

3 public:

4 CAVIFile()

5 {

6 InitializeCriticalSection(&m_criticalSection); // 初始化临界区

7 }

8 HRESULT OpenFile(const string& strFileName, const string& strDirectoryPath)

9 {

10 // ....

11 EnterCriticalSection(&m_criticalSection);

12 SetCurrentDirectory(strDirectoryPath.c_str());

13 // ...

14 LeaveCriticalSection(&m_criticalSection);

15 //...

16 }

17 // ...

18 private:

19 // ...

20 // 整个类设置当前目录的互斥锁

21 static CRITICAL_SECTION m_criticalSection;

22 };

23 CRITICAL_SECTION CAVIFile::m_criticalSection;

  但是上面的代码还是有问题,那么就是每生成一个CAVIFile对象,就会InitializeCriticalSection(&m_criticalSection);一次,这是有问题的,m_criticalSection是静态成员变量,这个临界区是CAVIFile类对象共享的,每个m_criticalSection应该只需要InitializeCriticalSection(&m_criticalSection)一次,而这里会InitializeCriticalSection()多次,这样可能导致资源的泄漏(对一个CRITICAL_SECTION对象InitializeCriticalSection()多次,会出现什么样的问题,我自己没有深入研究过,这里只是猜测!!但是CRITICAL_SECTION对象正常只需要InitializeCriticalSection()操作一次)。

喜欢 (88) or分享 (0)
首页  上一页  12345678910  下一页 尾页 共73条记录 6/10

网友评论:7

  1. 小编 1年前 (2015-03-22) #5

    软件测试入门 :mrgreen:

留言主题 *

您的姓名 *

电子信箱:

电话号码:

请你留言: