zoukankan      html  css  js  c++  java
  • C++开发过程多线程同步lock的实现

    在程序开发过程经常使用到多线程,而多线程始终与锁存在紧密地联系,以下详细的介绍如何在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

    待续。。。

  • 相关阅读:
    django-based blog- mezzanine
    echo "hello" | nc -4t -w1 localhost 8001
    boost静态链接的问题 -lgcc_s
    Vim 新用法
    解决docker中DNS查询的问题
    centos 升级GCC/G++
    enable c++11 in autoconf in fucking gnu auto tools
    Fucking "pkg-config not found"
    在CentOS 6.X 上面安装 Python 2.7.X
    redis sentinel 配置
  • 原文地址:https://www.cnblogs.com/chengbing2011/p/4274654.html
Copyright © 2011-2022 走看看