Почему JavaScript не поддерживает многопоточность? - PullRequest
239 голосов
/ 02 сентября 2008

Это преднамеренное дизайнерское решение или проблема с нашими современными браузерами, которая будет исправлена ​​в следующих версиях?

Ответы [ 17 ]

165 голосов
/ 02 сентября 2008

JavaScript не поддерживает многопоточность, потому что интерпретатор JavaScript в браузере является однопоточным (AFAIK). Даже Google Chrome не позволяет одновременно запускать JavaScript-код одной веб-страницы, поскольку это может вызвать серьезные проблемы с параллелизмом на существующих веб-страницах. Все, что делает Chrome - это разделяет несколько компонентов (разные вкладки, плагины и т. Д.) На отдельные процессы, но я не могу представить, чтобы на одной странице было несколько потоков JavaScript.

Однако вы можете использовать, как было предложено, setTimeout, чтобы разрешить какое-то планирование и «поддельный» параллелизм. Это заставляет браузер восстановить контроль над потоком рендеринга и запустить код JavaScript, предоставленный для setTimeout, по истечении заданного количества миллисекунд. Это очень полезно, если вы хотите, чтобы окно просмотра (что вы видите) обновлялось при выполнении операций с ним. Просто перебирая, например, координаты и соответствующее обновление элемента просто позволят вам увидеть начальную и конечную позиции, и ничего между ними.

Мы используем библиотеку абстракций в JavaScript, которая позволяет нам создавать процессы и потоки, которые управляются одним и тем же интерпретатором JavaScript. Это позволяет нам выполнять действия следующим образом:

  • Процесс А, Поток 1
  • Процесс A, Поток 2
  • Процесс B, Поток 1
  • Процесс A, Поток 3
  • Процесс A, Поток 4
  • Процесс B, Поток 2
  • Процесс паузы A
  • Процесс B, Поток 3
  • Процесс B, Поток 4
  • Процесс B, Поток 5
  • Запустить процесс A
  • Процесс А, Поток 5

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

Для будущего JavaScript, проверьте это: https://developer.mozilla.org/presentations/xtech2006/javascript/

22 голосов
/ 02 сентября 2008

Традиционно JS предназначался для коротких, быстро выполняющихся фрагментов кода. Если у вас были серьезные вычисления, вы делали это на сервере - идея JS + HTML app , которая долгое время работала в вашем браузере и выполняла нетривиальные задачи, была абсурдной.

Конечно, теперь у нас это есть. Но браузерам понадобится немало времени, чтобы наверстать упущенное - большинство из них было разработано на основе однопоточной модели, и изменить это непросто. Google Gears обходит многие потенциальные проблемы, требуя изолированного фонового выполнения - не нужно менять DOM (так как это не поточно-ориентировано), нет доступа к объектам, созданным основным потоком (так же). Несмотря на ограниченность, это, вероятно, будет наиболее практичным проектом в ближайшем будущем, поскольку он упрощает дизайн браузера и снижает риск, связанный с тем, что неопытные JS-кодеры могут связываться с потоками ...

@ Марсио :

Почему по этой причине не реализована многопоточность в Javascript? Программисты могут делать с инструментами все, что им захочется.

Итак, давайте не будем давать им инструменты, которые настолько просто неправильно использовать , что любой другой веб-сайт, который я открываю, заканчивает тем, что ломает мой браузер. Наивная реализация этого привела бы вас прямо на территорию, которая вызывала много головных болей у MS во время разработки IE7: авторы дополнений быстро и свободно играли с моделью потоков, что приводило к скрытым ошибкам, которые становились очевидными, когда жизненные циклы объектов менялись в основном потоке , ПЛОХОЙ. Если вы пишете многопоточные дополнения ActiveX для IE, я думаю, это идет с территорией; не значит, что нужно идти дальше.

19 голосов
/ 30 апреля 2010

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

Потоковая безопасность данных гарантируется, потому что все данные, передаваемые на / с рабочего, сериализуются / копируются.

Для получения дополнительной информации читайте:

http://www.whatwg.org/specs/web-workers/current-work/

http://ejohn.org/blog/web-workers/

10 голосов
/ 08 марта 2014

Multithread.js оборачивает Web Workers и обеспечивает простую многопоточность в JS Работает на всех новых браузерах, включая iOS Safari. :)

10 голосов
/ 02 сентября 2008

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

Просто сделайте так, чтобы ваша функция немного поработала, а затем вызовите что-то вроде:

setTimeout(function () {
    ... do the rest of the work...
}, 0);

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

7 голосов
/ 02 сентября 2008

Вы имеете в виду, почему язык не поддерживает многопоточность или почему движки JavaScript в браузерах не поддерживают многопоточность?

Ответ на первый вопрос заключается в том, что JavaScript в браузере предназначен для запуска в песочнице и независимым от машины / ОС способом: добавление поддержки многопоточности усложнит язык и слишком привязает язык к ОС .

4 голосов
/ 02 сентября 2008

Как сказал Мэтт Б, вопрос не очень ясен. Предположим, что вы спрашиваете о поддержке многопоточности на языке: потому что это не требуется для 99,999% приложений, работающих в браузере в настоящее время. Если вам это действительно нужно, есть обходные пути (например, использование window.setTimeout).

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

3 голосов
/ 02 апреля 2012

Корпорация Intel проводила некоторые исследования с открытым исходным кодом о многопоточности в Javascript, недавно она была продемонстрирована на GDC 2012 Вот ссылка для видео . Исследовательская группа использовала OpenCL, которая в первую очередь ориентирована на наборы микросхем Intel и ОС Windows. Проект с кодовым названием RiverTrail и код доступен на GitHub

Еще несколько полезных ссылок:

Создание вычислительного шоссе для веб-приложений

2 голосов
/ 07 декабря 2015

В настоящее время некоторые браузеры поддерживают многопоточность. Так что, если вам это нужно, вы можете использовать определенные библиотеки. Например, просмотрите следующие материалы:

2 голосов
/ 06 сентября 2018

Node.js 10.5+ поддерживает рабочие потоки в качестве экспериментальной функции (вы можете использовать ее с - экспериментальный-рабочий флаг включен): https://nodejs.org/api/worker_threads.html

Итак, правило таково:

  • если вам нужно выполнить операции ввода-вывода с привязкой , то используйте внутренний механизм (он же callback / обещание / async-await)
  • если вам нужно выполнить операции с привязкой к процессору , используйте рабочие потоки.

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

В противном случае, если вам нужно выполнить большую загрузку ЦП с помощью анонимной функции, вы можете использовать https://github.com/wilk/microjob, крошечную библиотеку, построенную на рабочих потоках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...