1 class TSemaphore 2 { 3 public: 4 //默认构造函数 5 TSemaphore(); 6 //由客户调用,以获得信号量 7 bool Acquire(); 8 //不再需要独占访问资源时,调用此函数 9 void Release(); 10 //有多少资源正在等待使用该资源 11 unsigned GetWaiters() const; 12 private: 13 //TSemaphore对象不能被复制或赋值 14 TSemaphore(const TSemaphore& other); 15 TSemaphore& operator=(const TSemaphore& other); 16 //细节省略 17 };
信号量(资源)的自动获得和释放:
用户在使用TSemphore这样的类时,必须记住使用Acquire成员函数来获得信号量。更重要的是,在离开函数前必须释放信号量(使用Release)。
1 class X 2 { 3 public: 4 //成员函数 5 void f(); 6 private: 7 TSemaphore _sem; 8 }; 9 10 void f() 11 { 12 //获得已锁定的信号量 13 _sem.Acquire(); 14 //希望完成的认为 15 if (/*某些条件*/) {/*一些代码*/_sem.Release(); return; } 16 else {/*其他代码*/_sem.Release(); } 17 }
必须记住每次退出函数时,都要释放信号量,否则会产生错误.
为了避免这样的麻烦,我们可以使用辅助类来自动获得和释放信号量
1 class TAutoSemaphore//辅助类 2 { 3 public: 4 TAutoSemaphore(TSemaphore& sem) 5 :_semaphore(sem) 6 { 7 _semaphore.Acquire(); 8 } 9 ~TAutoSemaphore() { _semaphore.Release(); } 10 private: 11 TSemaphore _semaphore; 12 }; 13 14 15 void X::f() 16 { 17 //创建TAutoSemaphore类对象,同时也获得信号量 18 TAutoSemaphore autosem(_sem); 19 //希望完成的任务 20 if (/*某些条件*/) {/*一些代码*/return; } 21 else{/*其他代码*/} 22 //autosem的析构函数在退出f()时,自动释放_sem信号量 23 }