在程序开发过程经常使用到多线程,而多线程始终与锁存在紧密地联系,以下详细的介绍如何在C++程序开发过程中自定义锁的几种方法。

1. 下面给出一段代码展现如何通过Mutex实现锁的功能(window platform):

Header File

//
// Mutex.h
//

namespace LockBase
{
    clasee Mutex
    {
    public:
        Mutex(HANDLE mutex);
        ~Mutex(void);
        operator bool() const;
        void Unlock(void);
        
    private:
        HANDLE m_mutex;
        boll b_unlocked;
        
    };
    
    
    #define lock(hmutex) for(LockBase::Mutex m_lock(hmutex);!m_lock;m_lock.UnLock())
}
View Code

Cpp File

//
// Mutex.cpp
//

#include"Mutex.h"

using namespace LockBae;

Mutex::Mutex(HANDLE mutex):b_unlocked(0)
{
    m_mutex=mutex;
    ::WaitForSingleObject(m_mutex,INFINE);
}

Mutex::~Mutex(void)
{
    ::ReleaseMutex(m_nutex);
}
void Mutex::Unlock(void)
{
    b_unlocked=true;
}

Mutex::operator bool() const
{
    return b_unlocked;
}
View Code

Using Demo

//
// using lock demo
//

HANDLE mutex=::CreateMutex(0.false;0);
lock(mutex)
{
    
}
View Code

 

2.通过CRITICAL_SECTION实现线程锁功能(window platform):

ScopedLock.h File

//
//    ScopeLock.h
//

#ifndef ScopedLock_INCLUDED
#define ScopedLock_INCLUDED

namespace LockBase
{
    template<class T>
    class scopedLock
    {
        // A class that simplifies thread synchronization
        // with a mutex.
        // The constructor accepts a Mutex (and optionally
        // a timeout value in milliseconds) and locks it.
        // The destructor unlocks the mutex.
        
    public:
        explicit ScopedLock(T& mutex): _mutex(mutex)
        {
            _mutex.lock();
        }
    
        ~ScopedLock()
        {
            _mutex.unlock();
        }
        
    private:
        T& _mutex;

        ScopedLock();
        ScopedLock(const ScopedLock&);
        ScopedLock& operator = (const ScopedLock&);
    };
    
    template<class T>
    class ScopedLockWithUnlock
    {
        // A class that simplifies thread synchronization
        // with a mutex.
        // The constructor accepts a Mutex (and optionally
        // a timeout value in milliseconds) and locks it.
        // The destructor unlocks the mutex.
        // The unlock() member function allows for manual
        // unlocking of the mutex.
        
    public:
        explicit ScopedLockWithUnlock(T& mutex): _pMutex(&mutex)
        {
            _pMutex->lock();
        }
    
        ~ScopedLockWithUnlock()
        {
            unlock();
        }
    
        void unlock()
        {
            if (_pMutex)
            {
                _pMutex->unlock();
                _pMutex = 0;
            }
        }

    private:
        T* _pMutex;

        ScopedLockWithUnlock();
        ScopedLockWithUnlock(const ScopedLockWithUnlock&);
        ScopedLockWithUnlock& operator = (const ScopedLockWithUnlock&);
    };
}        //namespace LockBase

#endif        //ScopedLock_INCLUDED
View Code

Mutex_WIN32.h File

//
// Mutex_WIN32.h
//

#ifndef Mutex_WIN32_INCLUDED
#define Mutex_WIN32_INCLUDED

namespace LockBase
{
    class MutexImpl
    {
    protected:
        MutexImpl();
        ~MutexImpl();
        void lockImpl();
        bool tryLockImpl();
        void unlockImpl();
        
    private:
        CRITICAL_SECTION _cs;
    };
    
    typedef MutexImpl FastMutexImpl;
    
    //
    // inlines
    //
    inline void MutexImpl::lockImpl()
    {
        try
        {
            EnterCriticalSection(&_cs);
        }
        catch (...)
        {
            throw std::runtime_error("cannot lock mutex");
        }
            
    }


    inline bool MutexImpl::tryLockImpl()
    {
        try
        {
            return TryEnterCriticalSection(&_cs) != 0;
        }
        catch (...)
        {
            throw std::runtime_error("cannot lock mutex");
        }
    }


    inline void MutexImpl::unlockImpl()
    {
        LeaveCriticalSection(&_cs);
    }
    
}    //namespace LockBase

#endif        // Mutex_WIN32_INCLUDED
View Code

Mutex_WIN32.cpp File

//
// Mutex_WIN32.cpp
//

namespace LockBase {


    MutexImpl::MutexImpl()
    {
        // the fct has a boolean return value under WInnNt/2000/XP but not on Win98
        // the return only checks if the input address of &_cs was valid, so it is safe to omit it
        InitializeCriticalSectionAndSpinCount(&_cs, 4000);
    }


    MutexImpl::~MutexImpl()
    {
        DeleteCriticalSection(&_cs);
    }
} // namespace LockBase
View Code

Mutex.cpp File

//
// Mutex.cpp
//

#ifdef _MSC_VER
#include "Mutex_WIN32.cpp"
#else
#include "Mutex_LINUX.cpp"
#endif


using namespace LockBase;

Mutex::Mutex()
{
}

Mutex::~Mutex()
{
}
View Code

待续。。。

 

posted on 2015-02-05 13:50  边城愚者  阅读(460)  评论(0编辑  收藏  举报