【问题标题】:Correct way to implement simple thread safe generic mutex实现简单线程安全通用互斥锁的正确方法
【发布时间】:2012-07-06 06:44:03
【问题描述】:

我想知道我实现通用互斥锁的方式是否是一种好的软件设计模式,它是线程安全的吗?

这是我的互斥锁类:

#ifdef HAVE_WINDOWS_H
void *CSimpleMutex::object;
#endif
#ifdef _PTHREADS
pthread_mutex_t CSimpleMutex::object;
#endif

CSimpleMutex::CSimpleMutex(bool lockable)
{
    isLockableMutex = lockable;
    if (!lockable)
    {
#ifdef _WINDOWS
        object = CreateMutex(NULL, false, NULL);
#endif
#ifdef _PTHREADS
        pthread_mutex_init(&object, NULL);
#endif
    }
    else
    {
#ifdef _WINDOWS
        InitializeCriticalSection(&mutex);
#endif
#ifdef _PTHREADS
        pthread_mutex_init(&mutex, NULL);
#endif
    }
}

CSimpleMutex::~CSimpleMutex()
{
    if (!isLockableMutex)
    {
#ifdef _WINDOWS
        if(object!=NULL)
        {
            CloseHandle(object);
        }
#endif
#ifdef _PTHREADS
        pthread_mutex_destroy(&object);
#endif
    }
    else
    {
#ifdef _WINDOWS
        DeleteCriticalSection(&mutex);
#endif
#ifdef _PTHREADS
        pthread_mutex_destroy(&mutex);
#endif  
    }
}

// Aquires a lock
void CSimpleMutex::Lock()
{
    if (!isLockableMutex)
        return;
#ifdef _WINDOWS
    EnterCriticalSection(&mutex);
#endif
#ifdef _PTHREADS
    pthread_mutex_lock(&mutex);
#endif
}

// Releases a lock
void CSimpleMutex::Unlock()
{
    if (!isLockableMutex)
        return;
#ifdef _WINDOWS
    LeaveCriticalSection(&mutex);
#endif
#ifdef _PTHREADS
    pthread_mutex_unlock(&mutex);
#endif
}

它是这样使用的:

class CEnvironment : public CHandleBase
{
    private:
        CSimpleMutex *mutex;
    public:
        CEnvironment(){mutex = new CSimpleMutex(true);};
        ~CEnvironment(){delete mutex;};
        void Lock() { mutex->Lock(); };
        void Unlock() { mutex->Unlock(); };
        void DoStuff(void *data);
};

当我想使用 CEnvironment 时,我会这样做:

env->Lock();
env->DoStuff(inData);
env->Unlock();

【问题讨论】:

  • 你建议的使用模式不是异常安全的。
  • 请注意,Windows 互斥锁(由CreateMutex 创建的互斥锁)是跨进程互斥锁,因此每个锁定/解锁操作都需要对内核进行系统调用,即使在没有竞争的情况下也是如此,这可能会很昂贵。如果您的进程中只需要互斥锁,请改用CRITICAL_SECTION objects,它有非常快的无竞争锁,不需要系统调用。
  • 嘿?什么是非 lockable 互斥锁?
  • @IngeHenriksen:无关紧要的问题。该术语是“进程间”,而不是“可锁定”。

标签: c++ multithreading pthreads mutex


【解决方案1】:

您通常会使用RAII 分别在进入和离开给定范围时获取和释放锁,以便在该范围内引发异常时自动释放锁。在您的情况下,您可以定义一个附加锁“守卫”类,该类在其构造函数中获取锁并在其析构函数中释放。例如,C++11 标准定义了几个 mutex 类和一个 std::lock_guard 类,它们提供了我刚才描述的行为。

Doug Schmidt 的论文“Strategized Locking, Thread-safe Interface, and Scoped Locking”提供了其他可能有用的设计细节和想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多