Я отлаживаю этот проект базы данных. Он включает доступ к SQLite для приложений более высокого уровня. Он предназначен для асинхронной работы, то есть имеет такие методы, как ExecuteRequestAsync () и IsRequestReady (). Когда вызывается ExecuteRequestAsync, он создает boost :: thread для выполнения работы и немедленного возврата функции. Когда приложение более высокого уровня решает, что оно больше не хочет результата запущенного запроса, оно может вызвать DumpRequest (), чтобы отменить его. Поскольку трудно корректно отменить запрос к базе данных, реализация DumpRequest просто поддерживает «поток монитора очистки», который ожидает «завершенные запросы», и удаляет их. Все потоки boost :: управляются с помощью 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);
Я создал этот проект модульного теста для проверки механизма выполнения и вывода запросов. Он выполняет запросы и случайным образом отменяет запущенные запросы и повторяется в течение нескольких тысяч проходов. Механизм оказался в порядке. Все заработало как положено.
Однако, наблюдая за проектом модульного тестирования через Process Explorer sysinternal, обнаруживается, что существует проблема утечки дескриптора. Каждые 500 проходов проходит счетчик, который увеличивается на 1 и никогда не возвращается обратно. Это дескриптор типа «событие», который увеличивается. Дескрипторы файла и потока не увеличиваются (конечно, число дескрипторов увеличивается с порождением потоков, но каждые сто проходов происходит вызов Sleep (10000) для ожидания их очистки, чтобы можно было наблюдать количество дескрипторов).
Я сам не управлял обработчиками событий. Они создаются boost :: thread при создании потока. Я гарантирую только изящное закрытие потоков, я понятия не имею, для чего используются События.
Мне интересно, сталкивался ли кто-нибудь с подобными проблемами? Что может быть причиной этой утечки? Достаточно ли надежен этот номер в Process Explorer, чтобы назвать его утечкой? Есть ли способ отследить и исправить это?
Я использую статически связанный буст 1.40 в Windows Vista с Visual C ++.