【发布时间】:2014-11-21 11:25:37
【问题描述】:
我正在使用 Live555 实现一个用于 IP 摄像机的 C++ RTPS 客户端。 我正在使用大部分 testRTSPClient 代码。
我也使用了 Poco 库和 Poco::Thread 类。
换句话说,每个摄像头的任何客户端都在一个单独的线程中运行,该线程拥有他的 Live555 对象实例(正如 live555-devel 所暗示的,任何线程都使用带有他的 UsageEnvironment 和 TaskScheduler 的实例。)。这是为了避免共享变量和同步的东西。它似乎运行良好且快速。
我的可运行(遵循 Poco 库要求)对象 IPCamera 的运行方法很简单:
void IPCamera::run()
{
openURL(_myEnv, "", _myRtspCommand.c_str(), *this); //taken from the testRTSPClient example
_myEnv->TaskScheduler().doEventLoop(&_watchEventLoopVariable);
//it runs until _watchEventLoopVariable change to a value != 0
//exit from the run;
}
运行完成后,我调用 join() 来关闭线程(顺便说一下,如果我不调用 myThread->join(),内存不会完全释放)。
关闭后,按照 Live555-devel 中的要求,我输入了我的代码:
void IPCamera::shutdown()
{
...
_myEnv->reclaim();
delete _myScheduler;
}
使用 Valgrind 检测内存泄漏我看到了一个奇怪的行为:
1) 案例:运行程序 - 关闭所有以正确方式运行的 IPCameras 的程序。
a) 在程序结束时,所有的析构函数都会被调用。
b) 从 doEventLoop() 退出。
c) 加入线程(实际上已经终止,因为它退出了run方法。
d) 如图所示销毁 _myEnv 和 _myScheduler。
e) 销毁所有其他对象,包括 IPCamera 和 Thread 关联。
-> Valgrind 没有发现内存泄漏。好的
现在问题来了。
2) 案例:我正在实现一个用例,其中 Poco::Timer 每隔 X 秒检查一次摄像头是否使用 ICMP ping 处于活动状态。它会引发一个事件(使用 Poco 事件),以防由于网络中断而无法响应,我执行以下操作:
IPCamera 关闭:
a) 将_watchEventLoopVariable = 1 从run方法中退出;
b) 如图所示,关闭与 IPCamera 关联的客户端
c) 加入线程
我不会破坏线程,因为我想在网络再次启动并且相机再次工作时重用它。在这种情况下: a)我设置 _eventWatchVariable = 0。 b) 让我们重新启动线程:myThread->run()
Valgrind 告诉我发现内存泄漏:60 个字节直接,20.000 个间接字节在线程中丢失,在 H264BufferdPackedFactory::createNewPacket(...),Live555 的一个类中。
【问题讨论】:
标签: c++ memory-leaks poco live555