Guard classes takes advantage of the fact that the destructor is always called for an object on the stack regardless of how you exit from the function scope.
Key Idea
unsigned __stdcall func(void *args)
{
static Lock lock;
Guard guard(lock);
// operations
return 0;
}
#ifndef _Guard_H_ #define _Guard_H_ #include "Lock.h" namespace examples { class Guard { public: Guard(Lock &lock) : m_lock(lock) { m_lock.acquire(); } ~Guard() { m_lock.release(); } private: Guard(); Guard(const Guard&); Guard& operator=(const Guard&); Lock &m_lock; }; } #endif //_Guard_H_The program demonstrates the use of Guard class to acquire() and release() the lock
The Complete Code
#include <windows.h> #include <process.h> #include <iostream> #include <assert.h> #include "Lock.h" #include "Guard.h" using namespace examples; static bool alive = true; static int current = 0; unsigned __stdcall put(void *args) { static Lock lock; while(alive) { Guard guard(lock); current = current + 10; ::Sleep(500); std::cout << current << std::endl; } return 0; } int main() { // create threads unsigned t1; HANDLE h1 = (HANDLE) ::_beginthreadex(0, 0, &put, 0, CREATE_SUSPENDED, &t1); assert(h1 != 0); unsigned t2; HANDLE h2 = (HANDLE) ::_beginthreadex(0, 0, &put, 0, CREATE_SUSPENDED, &t2); assert(h2 != 0); // start threads ::ResumeThread(h1); ::ResumeThread(h2); ::Sleep(10000); alive = false; ::WaitForSingleObjectEx(h1, INFINITE, false); ::WaitForSingleObjectEx(h2, INFINITE, false); ::CloseHandle(h1); ::CloseHandle(h2); return 0; }
References:
Exception Safe Code
Thinking in C++ Practical Programming
No comments:
Post a Comment