boost :: thread导致小事件句柄泄漏?

时间:2009-11-16 07:14:45

标签: c++ windows boost memory-leaks handle

我正在调试这个数据库项目。它包含了对更高级别应用程序的SQLite访问。它被设计为异步运行,也就是说,它具有ExecuteRequestAsync()和IsRequestReady()等方法。当调用ExecuteRequestAsync时,它会生成一个boost :: thread来完成这项工作并立即返回该函数。当更高级别的应用程序确定它不再需要正在运行的请求的结果时,它可以调用DumpRequest()来取消它。由于很难正常取消数据库请求,因此DumpRequest的实现只维护一个“清理监视器线程”,它等待“已完成的请求”并将其删除。所有boost :: threads都通过boost :: shared_ptr进行管理,如:

boost::shared_ptr<boost::thread> my_thread = new boost::thread(boost::bind(&DBCon::RunRequest, &this_dbcon));

当它不再需要(被取消)时:

vector<boost::shared_ptr<boost::thread> > threads_tobe_removed;
// some iteration
threads_tobe_removed[i].get()->join();
threads_tobe_removed.erase(threads_tobe_removed.begin()+i);

我创建了这个单元测试项目来测试执行和转储请求的机制。它运行请求并随机取消正在运行的请求,并重复几千次传递。结果证明这个机制没问题。一切都按预期工作。

但是,通过sysinternal的Process Explorer观察单元测试项目,发现存在句柄泄漏问题。每传500次,手柄数增加1,永不返回。这是“事件”类型句柄正在增加。文件和线程句柄没有增加(当然,句柄的数量随着线程的产生而增加,但是每100次传递都会进行一次Sleep(10000)调用以等待它们被清理,以便可以观察到句柄数)。

我自己没有管理事件句柄。它们是在创建线程时由boost :: thread创建的。我只保证优雅地关闭线程,我不知道事件的用途是什么。

我想知道是否有人遇到过类似的问题?这可能是造成这种泄漏的原因? Process Explorer中的这个数字是否足够可靠,称其为句柄泄漏?有没有办法追踪和修复它?

我在Windows Vista上使用静态链接的boost 1.40,使用Visual C ++。

1 个答案:

答案 0 :(得分:1)

访问threads_tobe_removed线程安全吗?如果不是,则当一个线程通过调用DumpRequest将一个线程添加到向量时,可能存在竞争条件,而清理监视器线程从向量中删除一个线程。因此,boost::thread - 对象可能会在不加入线程的情况下被销毁,这会使线程在没有关联对象的情况下运行,这可能会解释泄漏。