Python 未调用PyBind11析构函数?
我有一个用Python 未调用PyBind11析构函数?,python,c++,destructor,pybind11,Python,C++,Destructor,Pybind11,我有一个用PyBind11包装的c++类。问题是:当Python脚本结束时,不会自动调用c++析构函数。这会导致无序退出,因为析构函数需要释放网络资源 作为一种解决方法,有必要显式删除Python对象,但我不明白为什么 请有人解释一下这里出了什么问题,以及当Python对象被垃圾收集时如何自动调用destructor Pybind11绑定代码: py::class_<pcs::Listener>(m, "listener") .def(py::init<const py
PyBind11
包装的c++
类。问题是:当Python
脚本结束时,不会自动调用c++
析构函数。这会导致无序退出,因为析构函数需要释放网络资源
作为一种解决方法,有必要显式删除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");
py::class_m(监听器)
.def(py::init(),R“pbdoc(
监控网络流量。
当检测到所需的数据源时,将连接一个客户端实例以使用该数据流。
在收到数据时重新构造数据,就像拼图一样。发出填补任何空白的请求。按顺序验证数据。
数据通过回调输出到Python。使用构造函数中指定的方法,构造函数必须接受字符串参数。
)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
#回调函数
def打印字符串(str):
打印(“Python;”+str)
lstnr=侦听器(打印字符串,'tcp://127.0.0.1:9001'、clientCertPath、serverCertPath、proxyCertPath、desiredSources、“时间序列数据”、enableCurve、enableVerbose)
#跑一分钟
cnt=0
当cnt<60时:
cnt+=1
时间。睡眠(1)
#出于某种原因需要显式调用析构函数
德尔斯特纳
在注释中提到的> > p>,这种行为的近因是Python垃圾收集器:当对象的引用计数器达到0时,垃圾收集器可能破坏对象(从而调用C++析构函数),但此时不必这样做。
这个想法在这里的答案中得到了更充分的阐述:
正如上面的链接中所提到的,如果您在Python中的对象生命周期结束时需要进行清理,一个很好的解决方案是,在对象的包装器(pybind11或Python本身)中定义\uuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu退出
,并释放网络资源,然后,在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)
使用侦听器(打印字符串,'tcp://127.0.0.1:9001,clientCertPath,serverCertPath,proxyCertPath,desiredSources,'time_series_data',enableCurve,enableVerbose)作为lstnr:
#跑一分钟
cnt=0
当cnt<60时:
cnt+=1
时间。睡眠(1)
在注释中提到的> > p>,这种行为的近因是Python垃圾收集器:当对象的引用计数器达到0时,垃圾收集器可能破坏对象(从而调用C++析构函数),但此时不必这样做。
这个想法在这里的答案中得到了更充分的阐述:
正如上面的链接中所提到的,如果您在Python中的对象生命周期结束时需要进行清理,一个很好的解决方案是,在对象的包装器(pybind11或Python本身)中定义\uuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu退出
,并释放网络资源,然后,在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)
使用侦听器(打印字符串,'tcp://127.0.0.1:9001,clientCertPath,serverCertPath,proxyCertPath,desiredSources,'time_series_data',enableCurve,enableVerbose)作为lstnr:
#跑一分钟
cnt=0
当cnt<60时:
cnt+=1
时间。睡眠(1)
请看这篇文章:请看这篇文章: