【问题标题】:Have an object on stack not for the entire lifetime of the function在函数的整个生命周期内都有一个对象在堆栈上
【发布时间】:2023-03-26 05:23:01
【问题描述】:

我有一个函数foo() 获取critical section 进行一些处理并释放critical section。现在有多个控制流,所以为了避免忘记释放锁,我想把它包装在一个类,这样析构函数就会自动释放锁。

class Lock
{
public:
    LPCRITICAL_SECTION m_a;
    Lock(CRITICAL_SECTION *a):m_a(a){EnterCriticalSection(a);}
    ~Lock(){LeaveCriticalSection(m_a);}
};

现在的问题是我有控制流,我想要获取锁,做一些事情然后释放它,然后继续其他处理。所以我不想等待释放锁直到函数结束时破坏将开始。有没有办法做到这一点。

【问题讨论】:

  • 锁需要在不同线程之间共享的实例。您将如何实现这一目标?
  • @DavidHeffernan 临界区需要在线程之间共享,但 Lock 不能。在线程之间共享锁违背了目的(并且违反了进入临界区的线程是唯一可以离开它的线程的规则)。
  • 好的,我明白了。我没有仔细阅读代码。我从 Barmar 的原始答案开始,它创建了一个锁的实例而没有传递一个关键部分。应该检查Q中的代码。

标签: c++ winapi raii


【解决方案1】:

使用本地块:

void myFunction() {
    // do stuff
    {
        Lock l(&critsec);
        // do stuff needing lock
    }
    // do more stuff
}

【讨论】:

  • 是的,就是这么简单。对关键部分使用本地块。不要在类析构函数中隐藏关键部分的释放。
  • @JustinRandall "不要在类析构函数中隐藏关键部分的释放" - 为什么不呢?这是 RAII 编程的前提,对于 C++ OOP 设计和 STL 库至关重要。在构造函数中获取临界区锁并在析构函数中释放它正是应该发生的事情
  • @RemyLebeau 因为正是 OPs 问题“我有控制流,我想获取锁,做某事然后释放它,然后继续其他处理。所以我不想等待释放锁,直到破坏开始时功能结束”
  • @JustinRandall 但是我们还是把release隐藏在析构函数中,只是为了解决等待函数结束运行的问题。
  • @JustinRandall OP 的问题是由于缺乏对嵌套范围的了解。使用析构函数是正确的解决方案,只需使用嵌套范围使析构函数在函数退出之前运行即可。
猜你喜欢
  • 2012-11-19
  • 2017-07-02
  • 1970-01-01
  • 2013-05-01
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
相关资源
最近更新 更多