gpt4 book ai didi

c++ - 使用 wxCRIT_SECT_LOCKER 时如何防止死锁

转载 作者:太空宇宙 更新时间:2023-11-04 11:50:48 26 4
gpt4 key购买 nike

我正在用 C++ 编写单例 Logger 类。此类为多线程提供日志记录 API。为了使其线程安全,我使用了 wxCRIT_SECT_LOCKER 宏。

假设我的 Logger 类中有以下函数(简单示例):

void Logger::error( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);

// do something such as getting/setting class members
m_err_cnt++;

do_log("Error: " + msg);
}

void Logger::warning( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);

// do something such as getting/setting class members
m_warn_cnt++;

do_log("Warning: " + msg);
}

void Logger::do_log( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);

// do something such as getting/setting class members
m_log_cnt++;


cout << msg << endl;
}

问题:

Logger::warning() 被调用时,我们将进入临界区两次,一次在 Logger::warning() 中,另一次在 *Logger 中::do_log()*。

如果你同意这个问题是真实的并且会导致死锁,我怎样才能避免多重锁(使用 wxCriticalSection 类/宏)。

最佳答案

通常所做的是创建不获取锁的内部 API,这些 API 由获取锁的公共(public) API 调用。

void Logger::error( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);
m_err_cnt++;
do_log_internal("Error: " + msg);
}

void Logger::warning( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);
m_warn_cnt++;
do_log_internal("Warning: " + msg);
}

void Logger::do_log( string msg )
{
wxCRIT_SECT_LOCKER(adapter_locker, gs_LogBufferShield);
do_log_internal(msg);
}

void Logger::do_log_internal( string msg )
{
m_log_cnt++;
cout << msg << endl;
}

但是,对于您的问题,您可能更愿意直接使用wxMutex,并在构造它时使用类型wxMUTEX_RECURSIVE。这样,互斥体就有计数了。当互斥量第一次被锁定时,计数设置为 1。如果同一个线程再次获取互斥量,它会增加计数。释放互斥量会减少计数。当计数达到 0 时,互斥锁被解锁。

关于c++ - 使用 wxCRIT_SECT_LOCKER 时如何防止死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18329309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com