Какие операции в узле являются потокобезопасными?

Я используюэтот подход хранить данные в глобальном массиве, размещающем http-сервер, где определенные запросы будут манипулировать глобальным массивом.

Я немного волнуюсь из-за проблем с многопоточностью при определенных операциях - главным образомpush а такжеsplice, Я представляю, если в одном запросе я итерирую по массиву и удаляю элементы на основе условия, в то время как в другом запросе я вызываю.push() в массиве, с которым у меня возникнут проблемы. Кто-нибудь может это подтвердить?

Я в основном пишу на C #, где даже простое приращение не является потокобезопасным (запуск 25 потоков, выполняющих i ++, не гарантирует, что i == 25 после того, как все сказано и сделано).

Update:

Я написал 5 примеров, чтобы продемонстрировать то, о чем я говорю. Тест 1 и Тест 3 работают нормально. Тест 2 завершается неудачей из-за ... того, что обычно называют проблемами потоков (независимо от того, являются ли они фактическими процессорами или нет) Тесты 4 и 5, когда они выполняются параллельно, похоже, работают (это означает, что у них нет проблем со столкновениями, таких как Тест 2).

http://pastebin.com/HcJHTDFY

Я использую ApacheBench для тестирования, делая 1000 параллельных запросов.

Это заставляет меня поверить, что Тест 1 и Тест 3 работают нормально, потому что nodejs не выполнит больше 1instance of the app.get('/test3'...) callback in parallel Функция JavaScript параллельно (блокировка?). Как только вы реализуете setInterval / setTimeout, он освобождает nodejs для выполнения другого экземпляра обратного вызова (неблокирующего?).

Я просто пытаюсь понять, какого чертаnon-blocking I/O model действительно значит. Означает ли это, что «можно сделать неблокирование с помощью setTimeout и setInterval, если вам нужна неблокировка, в противном случае мы будем блокировать запуск любых других функций внешнего уровня до тех пор, пока мы не исчерпаем функцию, которую мы»; на & quot ;? Я чувствую, что это необходимо знать, чтобы у меня не возникало проблем с мыслью, что я могу реализовать что-то вроде / test2 и быть в полной безопасности.

Также, если я пытаюсь быть неблокирующим с моими обратными вызовами, должен ли я действительно звонитьsetTimeout(code, 1)? Или есть лучший способ?

Ответы на вопрос(2)

Решение Вопроса

Все потокобезопасны.

Нет потоков, JavaScript является однопоточным, невозможно одновременно запустить два оператора javascript.

Кроме того, вы все равно не должны использовать глобалы, потому что глобалы - это зло

Edit:

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

В узле все, что не является асинхронными блоками. Единственные асинхронные вещи, которые у вас есть, это setTimeout / setInterval / process.nextTick и любые асинхронные операции ввода-вывода.

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

Я написал статью оЧто значит быть неблокирующим

 Langdon05 апр. 2012 г., 01:45
Между прочим, JavaScript может быть однопоточным, но nodeJS представляется многопоточным, в противном случае последующие запросы к встроенному http-серверу не смогут вернуться до завершения первого. Такжеstackoverflow.com/questions/7018093/…
 05 апр. 2012 г., 02:01
@ Лэнгдон, тебе все равно, ты никогда не видишь темы. Это все равно что спросить "Безопасен ли поток SQL?" Несмотря на то, что реализация движка SQL использует потоки где-то на несколько уровней ниже, вы их никогда не видите и не заботитесь о них, это всего лишь детали реализации.
 05 апр. 2012 г., 01:57
@Langdon, является ли он многопоточным или нет, является деталью реализации, о которой вы не должны заботиться. Все, что он делает, это асинхронный ввод-вывод, либо непосредственно на уровне ядра, либо эмулирует асинхронный ввод-вывод с использованием пулов потоков.
 Langdon05 апр. 2012 г., 02:00
Но мне нужно позаботиться о том, чтобы использовать глобальную переменную для хранения данных. Хотя, возможно, из того, что вы говорите, я должен пересмотреть свой подход. Я попытаюсь написать несколько тестов, чтобы доказать / опровергнуть то, о чем я думаю.
 Langdon05 апр. 2012 г., 01:43
Итак, когда nodeJs / V8 входит в функцию () {}, которую я написал, никакие другие мои функции не будут выполнены, кроме тех, которые я вызываю внутри (как обратные вызовы)?

Райнос в основном прав. Но только то, что JavaScript является однопоточным, не означает, что вы можете ослабить охрану. Вы все еще должны знать о темах. Хорошим примером, иллюстрирующим это, является то, как socket.io поддерживает соединение с различными клиентами и все еще может отслеживать эти клиенты.

Функциональная часть программирования на JavaScript работает с помощью привязки переменных (например ... A LOT). Незнание потоков заставляет вас ошибочно полагать, что ваши переменные правильно связаны. Как и в случае с socket.io, как вы можете быть уверены, что соединение, которое вы получаете, является клиентом, который, по вашему мнению, вы получаете? Что если ссылочная привязка пошла не так и соединение фактически ссылается на другого клиента?

Это тот тип вещей, которые вы должны быть осторожны.

 05 апр. 2012 г., 14:59
Чтобы дать реальную обратную связь / критику. Когда «ссылка привязки пойдет не так». Когда соединение ссылается на другой «клиент». Да, есть ловушки параллелизма, о которых вы должны знать, но вы их не описываете, и они не связаны с потоками.
 23 февр. 2016 г., 20:36
@ming_codes Вы правы, ваш ответ правильный.
 05 апр. 2012 г., 02:29
JavaScript не имеет передачи по ссылке. Это и чепуха, о которой вы говорите, не имеет никакого отношения к темам. node.js даже не использует потоки, если ОС поддерживает асинхронный ввод-вывод на уровне ядра
 Langdon05 апр. 2012 г., 14:11
@ lightblade Ненавистники ...

Ваш ответ на вопрос