【问题标题】:Problems with nested object in functional object of the tbb::flow::graphtbb::flow::graph 的功能对象中嵌套对象的问题
【发布时间】:2015-10-30 16:10:52
【问题描述】:

我有一个函数对象,用作 multifunction_node 的主体:

class module
{
private:
    bool valid;

    QString description;

    bool hasDetectionBranch;
    tDataDescription bufData;

    void* dllObject; //<-- This is a pointer to an object constructed with help of the external dll

    qint64 TimeOut;

public:

    module(const QString& _ExtLibName);
    virtual ~module();

    void operator() (pTransmitData _transmitData, multi_node::output_ports_type &op);
};

“dllObject”是在对象“模块”的构造时创建的:

module::module(const QString& _ExtLibName) :
    valid(true), hasDetectionBranch(false)
{
    GetObjectDescription = (tGetObjectDescription)QLibrary::resolve(_ExtLibName, "GetObjectDescription");
    CreateObject = (tCreateObject)QLibrary::resolve(_ExtLibName, "CreateObject");
    DestroyObject = (tDestroyObject)QLibrary::resolve(_ExtLibName, "DestroyObject");

    if (!CreateObject || !DestroyObject || !GetObjectDescription)
        valid = false;
    else
    {
        description = QString(GetObjectDescription());
        dllObject = CreateObject();
    }
}

这就是“dllObject”被销毁的时候:

module::~module()
{
    if (valid)
    {
        DestroyObject(dllObject);
    }
}

我已经建立了一个小图表:

void MainWindow::goBabyClicked(void)
{
    module mod(QString("my.dll")); //<-- Here is OK and mod.dllObject is correct
    if (!mod.isValid())
    {
        qDebug() << "mod is invalid!\n";
        return;
    }

    first fir(input);
    folder fol(QString("C:/out"), 10000);

    graph g;

    source_node<pTransmitData> src(g, fir, false);

    multi_node mnode(g, tbb::flow::serial, mod); //<-- WTF? ~module() is executed!

    function_node<pTransmitData> f(g, tbb::flow::serial, fol);

    make_edge(src, mnode);
    make_edge(mnode, f);

    src.activate();

    g.wait_for_all();
}

所以我有两个问题: 1) 为什么执行 ~module() 以及如何防止这种情况? 2) 如何正确保存嵌套对象的指针?

更新添加了一些虚拟代码以防止第一次破坏 dllObject:

bool b = false;
module::~module()
{
    if (valid && b)
    {
        DestroyObject(dllObject);
    }
    if (!b)
        b = true;
    valid = false;
}

现在它按预期工作,但看起来很丑:/

【问题讨论】:

  • 什么是multi_node?我不熟悉 TBB Flow Graph,但我尝试寻找它。我找到的名字最接近的班级是multifunction_node...

标签: c++ tbb tbb-flow-graph


【解决方案1】:

最大,

我假设您有一个 typedefmulti_node,这与参考手册示例中的类似。

multifunction_node 的构造函数具有以下签名:

multifunction_node( graph &g, size_t concurrency, Body body );

body 对象在参数传递过程中和节点构建过程中被复制,因此在构建过程中创建了两个 mod 副本(实际上是三个,因为还存储了 body 的初始副本以供重新使用使用rf_reset_bodies 调用reset() 时初始化主体)。您看到的析构函数调用可能是那些用于销毁副本的调用。

body 对象还应该定义一个复制构造函数,或者能够接受 default-copy-constructor 来复制 body。我认为QString 定义了一个复制构造函数,但我不知道tDataDescription 之类的字段。 (我以为我们已经在参考手册中介绍了 Body 对象的基本要求,但我仍在寻找该部分。)无论如何,Body 类必须是 CopyConstructible,因为它被复制了多次。

问候, 克里斯

【讨论】:

  • Mike 找到了参考资料;它在参考指南中,在 Flow Graph 下,multifunction_node 上的页面中对主体有要求。对使用 Body 的节点 continue_node、function_node 和 source_node 重复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多