boost :: thread вызывает маленькую утечку дескриптора события? - PullRequest
1 голос
/ 16 ноября 2009

Я отлаживаю этот проект базы данных. Он включает доступ к 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 ++.

1 Ответ

1 голос
/ 16 ноября 2009

Является ли доступ к threads_tobe_removed поточно-ориентированным? В противном случае может возникнуть состояние гонки, когда один поток добавляет поток к вектору с помощью вызова DumpRequest, в то время как поток мониторинга очистки удаляет поток из вектора. Таким образом, boost::thread -объекты могут быть уничтожены без предварительного присоединения к потоку, что приведет к тому, что поток будет работать без связанного объекта, что может объяснить утечку.

...