Многоядерные процессоры и проблемы ими порождаемые



             

Пути решения проблем - часть 2


В отсутствии исходных текстов эту затею осуществить труднее, но все-таки возможно. Сначала необходимо найти переменные, к которым идет обращение из нескольких потоков. Это делается так: ищутся все вызовы CreateThread()/_beginthread(), определяется стартовый адрес функции потока и создается дерево функций, вызываемых этим потоков (для этого удобно использовать скрипт func_tree.idc от mammon'а, который можно скачать с www.idapro.com). Перечисляем глобальные переменные, упомянутые в этих функциях и если одна и та же переменная встречается в деревьях двух разных потоков — смотрим на нее пристальным взглядом, пытаясь ответить на вопрос: может ли она быть источником проблем или нет? Если переменная не используется для обмена данными между потоками — замещаем все обращения к ней на переходник к нашему обработчику, размещенному в свободном месте файла, который, используя вызовы TslSetValue()/TslGetValue(), записывает/считывает ее содержимое. Если же переменная используется для обмена данными между потоками — окружаем ее критическими секциями или другими механизмами синхронизации.

Естественно, все это требует правки исполняемого файла (и при том довольно значительной). Без соответствующих знаний и навыков за такую задачу не стоит и браться! Правда, есть шанс, что проблему удастся разрешить и без правки — поменяв приоритеты потоков. Если один из двух (или более) потоков, использующий разделяемые данные без синхронизации, получит больший приоритет, чем остальные, "расстановка сил" немедленно изменится и, возможно, она изменится так, что порча данных станет происходить не так часто, как прежде. Нужные значения приоритетов подбираются экспериментально, а задаются API-функций SetThreadPriority(), принимающий дескриптор потока. Вот тут-то и начинаются проблемы. Мы можем легко узнать идентификатор потока через функции TOOLHELP32: CreateToolhelp32Snapshot(),Thread32First()/Thread32Next(), остается "всего лишь" преобразовать его в дескриптор.


Содержание  Назад  Вперед