• 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

    待续。。。

  • 相关阅读:
    synthetic-load-generator 一个不错的opentracing trace && metrics && logs 生成工具
    记一次php.ini配置不合理造成系统加载偏慢问题
    Data-Prepper opendistro 开源的基于es 的trace 分析工具
    使用babel-standalone 让浏览器支持es6特性
    tempo grafana 团队开源的分布式追踪框架
    grafana/agent grafana 团队开源的兼容prometheus 的agent
    k6 集成goja 的部分集成说明
    spf13/afero 通用文件系统试用
    goja 支持es6的一种方法
    salesforce 跨组织数据可见性的方案
  • 原文地址:https://www.cnblogs.com/chengbing2011/p/4274654.html
Copyright © 2020-2023  润新知