Почему JavaScript не поддерживает многопоточность?

StackOverflow https://stackoverflow.com/questions/39879

Вопрос

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

Это было полезно?

Решение

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

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

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

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

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

Что касается будущего JavaScript, ознакомьтесь с этим:https://developer.mozilla.org/presentations/xtech2006/javascript/

Другие советы

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

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

@marcio :

  

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

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

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

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

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

http://www.whatwg.org/specs/web-workers / ток-работа /

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Новый браузер, который Google должен выпустить сегодня (Google Chrome), выполняет некоторый код параллельно, разделяя его по ходу работы.

Основной язык, конечно, может иметь ту же поддержку, что и, скажем, Java, но поддержка чего-то вроде параллелизма Erlang находится далеко за горизонтом.

Насколько я слышал, в Google Chrome будет многопоточный JavaScript, так что это "текущие реализации" проблема.

Согласно этой статье уже можно реализовать JavaScript нарезание резьбы.

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

Однако вы можете использовать функцию eval для обеспечения параллелизма в некотором объеме

/* content of the threads to be run */
var threads = [
        [
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');",
            "document.write('Foo <br/>');"
        ],
        [
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');",
            "document.write('Bar <br/>');"
        ]
    ];

window.onload = function() {
    var lines = 0, quantum = 3, max = 0;

    /* get the longer thread length */
    for(var i=0; i<threads.length; i++) {
        if(max < threads[i].length) {
            max = threads[i].length;
        }
    }

    /* execute them */
    while(lines < max) {
        for(var i=0; i<threads.length; i++) {
            for(var j = lines; j < threads[i].length && j < (lines + quantum); j++) {
                eval(threads[i][j]);
            }
        }
        lines += quantum;
    }
}

вы можете использовать Jetworker, упаковщик на веб-работника https://github.com/uxitten/jetworker

Многопоточность с использованием javascript, безусловно, возможна с использованием веб-приложений HTML5.

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

Существует множество фреймворков, позволяющих структурировать программирование между потоками, в том числе OODK-JS, фреймворк OOP js, поддерживающий параллельное программирование. https://github.com/GOMServices/oodk-js-oop-for-js

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top