Анализ многопоточных [закрытых] программ

Короткие и простые: поскольку элементы, которые вы ищете, не существуют в документе (пока).


В оставшуюся часть этого ответа я буду использовать getElementById как пример, но то же самое относится к getElementsByTagName , querySelector и любому другому методу DOM, который выбирает элементы.

Возможные причины

Есть две причины, по которым элемент может не существовать:

  1. Элемент с переданным идентификатором действительно не существует в документе. Вы должны дважды проверить, что идентификатор, который вы передаете на getElementById, действительно соответствует идентификатору существующего элемента в (сгенерированном) HTML и что у вас не было с ошибкой идентификатор (идентификаторы чувствительный !). Кстати, в большинстве современных браузеров , которые реализуют методы querySelector() и querySelectorAll(), нотация стиля CSS используется для извлечения элемента его id, например: document.querySelector('#elementID'), в отличие от способа, с помощью которого элемент извлекается его id в [[16]; в первом символе # необходимо, во втором это приведет к тому, что элемент не будет извлечен.
  2. Элемент не существует в данный момент , который вы вызываете getElementById ].

Последний случай довольно распространен. Браузеры анализируют и обрабатывают HTML сверху вниз. Это означает, что любой вызов элемента DOM, который встречается до появления этого элемента DOM в HTML, не будет выполнен.

Рассмотрим следующий пример:



Появляется div после script. В настоящий момент сценарий выполняется, элемент не существует , но и getElementById вернут null.

jQuery

То же самое относится к все селекторы с jQuery. jQuery не найдет элементов, если вы ошибочно написали ваш селектор, или вы пытаетесь выбрать их , прежде чем они на самом деле существуют .

Добавленный поворот - это когда jQuery не найден потому, что вы загрузили скрипт без протокола и запускаетесь из файловой системы:


этот синтаксис используется, чтобы позволить сценарию загружаться через HTTPS на странице с протоколом https: // и для загрузки HTTP-версии на странице с протоколом http: //

У этого есть неудачный побочный эффект попытки и невозможность загрузить file://somecdn.somewhere.com...


Решения

Прежде чем позвонить getElementById (или любой метод DOM, если на то пошло), убедитесь, что существуют элементы, к которым вы хотите получить доступ, т.е. загружается DOM.

Это может быть обеспечено просто добавив ваш JavaScript после к соответствующему элементу DOM

, и в этом случае вы также можете поместить код непосредственно перед тегом закрывающего тела () (все DOM элементы будут доступны в момент выполнения скрипта). [/ g3 6]

Другие решения включают прослушивание событий load [MDN] или DOMContentLoaded [MDN] . В этих случаях не имеет значения, где в документе вы помещаете код JavaScript, вам просто нужно запомнить, чтобы весь обработчик DOM обрабатывался в обработчиках событий.

Пример:

window.onload = function() {
    // process DOM elements here
};

// or

// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function() {
    // process DOM elements here
});

Более подробную информацию об обработке событий и различиях браузера см. в статьях на странице quirksmode.org .

jQuery

Сначала убедитесь, что jQuery загружен правильно , Используйте инструменты разработчика браузера , чтобы узнать, был ли найден файл jQuery и исправлен ли URL-адрес, если он не был (например, добавьте схему http: или https: в начале, отрегулируйте путь, и т. д.)

Прослушивание событий load / DOMContentLoaded - это именно то, что делает jQuery с .ready() [docs] . Весь ваш код jQuery, который влияет на элемент DOM, должен находиться внутри этого обработчика событий.

На самом деле в учебнике j8uery явно указано:

Как почти все, что мы делаем при использовании jQuery, читает или манипулирует объектной моделью документа (DOM), мы должны убедиться, что мы начинаем добавлять события и т. д., как только DOM готов.

Для этого мы регистрируем готовое событие для документа.

$(document).ready(function() {
   // do stuff when DOM is ready
});
blockquote>

В качестве альтернативы вы также можете использовать сокращенный синтаксис:

$(function() {
    // do stuff when DOM is ready
});

Оба эквивалентны.

7
задан Community 23 May 2017 в 12:33
поделиться

7 ответов

Инвестируйте в копию VTune Intel и его потока профильные инструменты. Это даст Вам обоим систему и исходное представление уровня поведения потока. Это, конечно, не собирается автодокументировать вещь для Вас, но должно быть реальной справкой, по крайней мере, в визуализации, что происходит при различных обстоятельствах.

Я думаю, что существует пробная версия, которую можно загрузить, так может стоить дать этому движение. Я только использовал версию Windows, но рассмотрение веб-страницы VTune она также имеет версию Linux.

6
ответ дан 6 December 2019 в 10:55
поделиться

Как начальная точка, я испытал бы желание добавить сообщения журнала трассировки в стратегических точках в рамках Вашего приложения. Это позволит Вам анализировать, как Ваши потоки взаимодействуют без опасности, что действие наблюдения потоков изменит их поведение (как мог иметь место с пошаговой отладкой). Мой опыт с платформой.NET, и мой привилегированный инструмент входа был бы log4net, так как это свободно, имеет обширные параметры конфигурации и, если Вы будете разумны в том, как Вы реализуете свой вход, это заметно не препятствует производительности Вашего приложения. С другой стороны, существует.NET, создал в Отладке (или Трассировка) класс в Системе. Пространство имен диагностики.

4
ответ дан 6 December 2019 в 10:55
поделиться

Я сфокусировался бы на блокировках общей памяти сначала (взаимные исключения и семафоры), поскольку они, скорее всего, вызовут проблемы. Взгляд, какое состояние защищается блокировками и затем определяет, какое состояние находится под защитой нескольких блокировок. Это даст Вам смысл потенциальных конфликтов. Взгляд на ситуации, где код, который содержит блокировку, обращается к методам (не забывают виртуальные методы). Попытайтесь устранить эти вызовы, где возможный (путем сокращения времени блокировка сохранена).

Учитывая список взаимных исключений, которые сохранены и общее представление о состоянии, которое они защищают, присвойте порядок блокировки (т.е. взаимное исключение A должен всегда браться перед взаимным исключением B). Попытайтесь осуществить это в коде.

Посмотрите, можно ли объединить несколько блокировок в ту, если на параллелизм не окажут негативное влияние. Например, если взаимное исключение A и B кажется, что у них могли бы быть мертвые блокировки, и схема упорядочивания легко не сделана, объедините их к одной блокировке первоначально.

Это не будет легким, но я для упрощения кода за счет параллелизма для получения дескриптора проблемы.

3
ответ дан 6 December 2019 в 10:55
поделиться

Это действительно тяжелая проблема для автоматизированных инструментов. Вы могли бы хотеть изучить модель, проверяющую Ваш код. Не ожидайте волшебные результаты: образцовые средства проверки очень ограничены в объеме кода и количестве потоков, которые они могут эффективно проверить.

Инструментом, который мог бы работать на Вас, являются ШАХМАТЫ (хотя это, к сожалению, только для Windows). BLAST является другим довольно мощным инструментом, но является очень трудным использовать и не может обработать C++. Википедия также перечисляет StEAM, о котором я не услышал прежде, но кажется, что это могло бы работать на Вас:

StEAM является образцовым средством проверки для C++. Это обнаруживает мертвые блокировки, отказы сегментации, из переменных диапазона и незавершающихся циклов.

С другой стороны, это, вероятно, помогло бы много попытаться сходиться код к небольшому количеству четко определенного (и, предпочтительно, высокий уровень) схемы синхронизации. Смешивая блокировки, семафоры и мониторы в той же кодовой базе напрашиваются на неприятности.

2
ответ дан 6 December 2019 в 10:55
поделиться

Одна вещь иметь в виду с использованием log4net или подобный инструмент состоит в том, что они изменяют синхронизацию приложения и могут часто скрывать базовые условия состязания. У нас был некоторый плохо написанный код для отладки и представленный вход, и это на самом деле удалило условия состязания и мертвые блокировки (или значительно уменьшил их частоту).

1
ответ дан 6 December 2019 в 10:55
поделиться

В Java у Вас есть выбор как FindBugs (для статического анализа байт-кода) для нахождения определенных видов непоследовательной синхронизации или многих динамический поток анализаторы от компаний как Coverity, JProbe, OptimizeIt, и т.д.

1
ответ дан 6 December 2019 в 10:55
поделиться

Не может UML помогать Вам здесь?

Если Вы перепроектируете свою кодовую базу в UML, то необходимо смочь нарисовать диаграммы классов, который показывает отношения между классами. Начиная с классов, методы которых являются точками входа потока, Вы видели который использование потока который класс. На основе моего опыта с Рациональным Повысился, это могло быть достигнуто с помощью перетаскивания; если никакие отношения между добавленным классом и предыдущими, то добавленный класс непосредственно не используется потоком, который запустился с метода, с которого Вы начали схему. Это должно давать Вам подсказать к роли каждого, распараллеливает.

Это также покажет "объекты данных", которые совместно используются и объекты, которые являются определенными для потока.

Если Вы рисуете большую диаграмму классов и удаляете все "объекты данных", то необходимо смочь к расположению, которые схематически изображают как облака, каждый облака, являющиеся потоком - или группа потоков, если связь и сцепление кодовой базы не ужасны.

Это будет только давать Вам одну часть загадки, но это могло быть полезно; я просто надеюсь, что Ваша кодовая база является не слишком грязной или слишком "процедурной", в этом случае...

1
ответ дан 6 December 2019 в 10:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: