【问题标题】:Deferred execution strategy in C++C++中的延迟执行策略
【发布时间】:2012-08-13 17:00:24
【问题描述】:

我有一个回调实现,其中未知的第三方在我的代码中调用函数指针。

但是,许多语言中的一个问题是函数返回后触发代码。例如,当调用回调并且我必须删除调用对象(并且在这种情况下,重新初始化它)时,从回调返回会导致异常。

假设我不能挂钩并且我不拥有/不能修改调用回调的代码,那么在函数返回后执行代码的最佳方式是什么?

我能想到的唯一真正的方法是设置某种状态机并让工作线程检查状态。但是,我预见到的问题是竞态条件,在重置回调返回和调用对象被重置之间调用回调。

是否有任何我不知道的功能,或者这是实现这种结果的最有效方式?

【问题讨论】:

  • “调用对象”究竟是什么?您是说属于对象 X 的某些代码在您的代码中调用了一个函数,而您的函数应该删除对象 X?如果是,何时?当函数被调用时,对象 X 显然仍在使用中,所以肯定不会。
  • @DavidSchwartz - 这正是正在发生的事情。
  • 是的,所以你有一个设计问题。您的 API 无法让您知道何时可以安全地删除对象。因此,要么修复 API,要么接受您将始终遇到竞争条件。
  • @DavidSchwartz - 这就是我的想法:/我可以处理比赛条件。它是 ASIO(音频)SDK,不用说它的组合很差。我可以更改提供的源/标头,但实现 COM 对象的第三方驱动程序将无法工作。
  • 你必须伪造它。保留最后一次访问对象的表格,如果“有一段时间”没有访问对象,则删除该对象。如果您删除它们时并不特别重要,如果您还没有进行扫描,例如一分钟,请在进入时进行扫描。否则,无论您需要多少次,都可以分派一个线程进行扫描。

标签: return deferred-execution


【解决方案1】:

它需要 c++11 或更高版本。但这就是我要做的。 您可以将其重写为使用函数指针,以便它可以在较旧的 c++ 版本上运行

#include <functional>
#include <iostream>

#define CONCACT_IMPL(x , y) x##y
#define CONCAT(x, y) CONCACT_IMPL(x, y)
#define deffered(x) auto CONCAT(__deffered, __COUNTER__)  = Defer(x);

struct Defer {
    Defer(std::function<void(void)> pFunc) : func(pFunc) {};
    std::function<void(void)> func;
    virtual ~Defer(){
        func();
    }
};

int main() {

    deffered([] () {
        std::cout << "deffered" << std::endl;
    });

    std::cout << "now" << std::endl;
}

输出 -->

now
deffered

【讨论】:

  • 这不适合 OP 中的用例(我记得我前一段时间遇到的问题,根本不可能做我想做的事)。不过我会接受这个,因为这是我以前使用过的模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 2019-04-06
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
相关资源
最近更新 更多