c++ - 互斥锁未解锁

标签 c++ mutex cocos2d-x

我使用互斥锁来锁定和解锁变量,因为我在更新周期中不断地从主线程调用 getter 并从另一个线程调用 setter。我在下面提供了 setter 和 getter 的代码

定义

bool _flag;
System::Mutex m_flag;

通话

#define LOCK(MUTEX_VAR) MUTEX_VAR.Lock();
#define UNLOCK(MUTEX_VAR) MUTEX_VAR.Unlock();

void LoadingScreen::SetFlag(bool value)
{
    LOCK(m_flag);
    _flag = value;
    UNLOCK(m_flag);
}

bool LoadingScreen::GetFlag()
{
    LOCK(m_flag);
    bool value = _flag;
    UNLOCK(m_flag);

    return value;
}

这在一半情况下工作得很好,但有时变量在调用 SetFlag 时被锁定,因此它永远不会被设置,从而扰乱代码流。

谁能告诉我如何解决这个问题?

编辑:

这是我最终采用的解决方法。这只是一个临时解决方案。如果有人有更好的答案,请告诉我。

bool _flag;
bool accessingFlag = false;

void LoadingScreen::SetFlag(bool value)
{
    if(!accessingFlag)
    {
        _flag = value;
    }
}

bool LoadingScreen::GetFlag()
{
    accessingFlag = true;
    bool value = _flag;
    accessingFlag = false;

    return value;
}

最佳答案

您遇到的问题(user1192878 暗示)是由于编译器加载/存储延迟所致。您需要使用 memory barriers实现代码。您可以声明 volatile bool _flag; .但这不需要 compiler memory barriers对于单 CPU 系统。多 CPU 解决方案需要硬件障碍(在维基百科链接下方);硬件屏障确保所有 CPU 都能看到本地处理器的内存/缓存。 mutex的使用在这种情况下不需要其他互锁。他们究竟完成了什么?它们只会造成死锁,并不需要。

bool _flag;
#define memory_barrier __asm__ __volatile__ ("" ::: "memory") /* GCC */

void LoadingScreen::SetFlag(bool value)
{
    _flag = value;
    memory_barrier(); /* Ensure write happens immediately, even for in-lines */
}

bool LoadingScreen::GetFlag()
{
   bool value = _flag;
   memory_barrier(); /* Ensure read happens immediately, even for in-lines */
   return value;
}

只有在同时设置多个值时才需要互斥锁。您也可以更改 bool输入 sig_atomic_tLLVM atomics .然而,这是相当迂腐的 bool将适用于大多数实际的 CPU 架构。 Cocoa's concurrency pages也有一些关于替代 API 的信息来做同样的事情。我相信 gcc 的内联汇编器 与 Apple 的编译器使用的语法相同;但这可能是错误的。

API 有一些限制。实例 GetFlag()返回,有事可调用SetFlag() . GetFlag()返回值就过时了。如果您有多位作家,那么您很容易错过一位 SetFlag() .如果更高级别的逻辑容易出现 ABA problems,这可能很重要.但是,所有这些问题在有/没有互斥量的情况下都存在。 内存屏障 仅解决编译器/CPU 不会缓存 SetFlag() 的问题很长一段时间,它会重新读取 GetFlag() 中的值.声明 volatile bool flag通常会导致相同的行为,但会产生额外的副作用,并且不会解决多 CPU 问题。

std::atomic<bool> 根据 stefan atomic_set(&accessing_flag, true);通常会在他们的实现中做与上面描述的相同的事情。如果它们在您的平台上可用,您可能希望使用它们。

关于c++ - 互斥锁未解锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115703/

相关文章:

json - 在cocos2dx中解析json文件

c++ - 文本文件到数组传输

c++ - 如何从稀疏矩阵中获取右下角的部分?

c++ - 如何将图像转换为缓冲区,以便我可以使用套接字编程将其发送过来? C++

c - 使用互斥体和条件变量调度多个线程

ios - 应用挂起在 __psynch_mutexwait

android - 我可以使用 Visual Studio 作为 IDE 进行 cocos2d-x 3.0rc2、c++ 开发吗?

android - Cocos2d-js:如何在Android和Ios中退出一个应用程序?

c++ - 使用 cvSaveImage 错误的 OpenCV C++ 错误:在 cv::_InputArray::type 中断言失败((标志和 FIXED_TYPE)!= 0)

c - C 中 pthread 的问题