【问题标题】:PyBind11 destructor not invoked?未调用 PyBind11 析构函数?
【发布时间】:2023-04-08 06:56:01
【问题描述】:

我有一个用PyBind11 包裹的c++ 类。问题是:当Python 脚本结束时,c++ destructor 不会被自动调用。这会导致退出混乱,因为网络资源需要由析构函数释放。

作为一种变通方法,有必要明确删除Python 对象,但我不明白为什么!

请有人解释这里出了什么问题以及如何在Python 对象被垃圾收集时自动调用destructor

Pybind11绑定代码:

py::class_<pcs::Listener>(m, "listener")
    .def(py::init<const py::object &, const std::string &, const std::string &, const std::string &, const std::string &, const std::set<std::string> &, const std::string & , const bool & , const bool & >(), R"pbdoc(
    Monitors network traffic.

    When a desired data source is detected a client instance is connected to consume the data stream.

    Reconstructs data on receipt, like a jigsaw.  Makes requests to fill any gaps.  Verifies the data as sequential.

    Data is output by callback to Python.  Using the method specified in the constructor, which must accept a string argument.
)pbdoc");

在 Python 中:

#Function to callback
def print_string(str):
    print("Python; " + str)

lstnr = listener(print_string, 'tcp://127.0.0.1:9001', clientCertPath, serverCertPath, proxyCertPath, desiredSources, 'time_series_data', enableCurve, enableVerbose)

#Run for a minute
cnt = 0
while cnt < 60:
    cnt += 1
    time.sleep(1)

#Need to call the destructor explicity for some reason    
del lstnr

【问题讨论】:

标签: python c++ destructor pybind11


【解决方案1】:

正如评论中提到的,此行为的直接原因是 Python 垃圾收集器:当对象的引用计数器变为零时,垃圾收集器可能销毁该对象(从而调用 c++ 析构函数),但它此时不必这样做

这里的答案更全面地阐述了这个想法:

https://stackoverflow.com/a/38238013/790979

正如上面链接中也提到的,如果您在 Python 中的对象生命周期结束时需要进行清理,那么一个不错的解决方案是 context management,您可以在其中定义 __enter____exit__在对象的包装器中(在 pybind11 或 Python 本身中),让 __exit__ 释放网络资源,然后在 Python 客户端代码中,类似:


with listener(print_string, 'tcp://127.0.0.1:9001', clientCertPath, serverCertPath, proxyCertPath, desiredSources, 'time_series_data', enableCurve, enableVerbose) as lstnr:
    # Run for a minute
    cnt = 0
    while cnt < 60:
        cnt += 1
        time.sleep(1)

【讨论】:

  • 感谢@charleslparker 的回答和解释。虽然我仍然没有解决这个问题,因为我一直在努力寻找有关如何在 PyBind11 绑定代码中实现 __enter____exit__ 的示例和文档。
猜你喜欢
  • 2017-04-28
  • 2013-07-07
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
相关资源
最近更新 更多