source

JavaScript가 멀티스레딩을 지원하지 않는 이유는 무엇입니까?

goodcode 2022. 9. 22. 00:23
반응형

JavaScript가 멀티스레딩을 지원하지 않는 이유는 무엇입니까?

고의적인 설계 결정입니까, 아니면 향후 버전에서 수정될 현재의 브라우저에 문제가 있습니까?

브라우저의 JavaScript 인터프리터는 단일 스레드(AFAIK)이기 때문에 JavaScript는 멀티스레딩을 지원하지 않습니다.심지어 구글 크롬조차도 하나의 웹 페이지의 자바스크립트를 동시에 실행하도록 놔두지 않을 것이다. 왜냐하면 이는 기존 웹 페이지에 엄청난 동시성 문제를 일으킬 것이기 때문이다.Chrome은 여러 컴포넌트(다른 탭, 플러그인 등)를 별도의 프로세스로 분리하는 것이 전부지만, 한 페이지에 여러 개의 JavaScript 스레드가 있는 것은 상상할 수 없습니다.

처럼 '아, 아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.setTimeout일정과 "가짜" 동시성을 허용하기 위해서입니다., 스레드의 , 「」에 공급된 JavaScript 합니다.setTimeout표시되는것)에 대한 하는 동안 것)를 갱신할 수 있도록 편리합니다.이 기능은 뷰포트에 대한 작업을 수행하는 동안 뷰포트(표시되는 항목)를 새로 고칠 수 있도록 하는 경우 매우 유용합니다.예를 들어 좌표를 반복하고 그에 따라 요소를 업데이트하기만 하면 시작 위치와 끝 위치만 볼 수 있으며 중간에 아무것도 표시되지 않습니다.

JavaScript에서 추상화 라이브러리를 사용하여 프로세스와 스레드를 모두 동일한 JavaScript 인터프리터로 관리할 수 있습니다.이를 통해 다음과 같은 방법으로 작업을 실행할 수 있습니다.

  • 프로세스 A, 스레드 1
  • 프로세스 A, 스레드 2
  • 프로세스 B, 스레드 1
  • 프로세스 A, 스레드 3
  • 프로세스 A, 스레드 4
  • 프로세스 B, 스레드 2
  • 프로세스 A의 일시정지
  • 프로세스 B, 스레드 3
  • 프로세스 B, 스레드 4
  • 프로세스 B, 스레드 5
  • 프로세스 A의 시작
  • 프로세스 A, 스레드 5

이것에 의해, 일정의 스케줄링이나, 병렬 처리, 스레드의 개시와 정지등의 조작이 가능하게 됩니다만, 진정한 멀티 스레딩은 아닙니다.진정한 멀티스레딩은 브라우저가 단일 페이지 멀티스레드(또는 여러 코어)를 실행할 수 있는 경우에만 유용하고, 그 어려움은 추가 가능성보다 훨씬 크기 때문에 언어 자체로는 구현되지 않을 것이라고 생각합니다.

JavaScript의 장래에 대해서는, https://developer.mozilla.org/presentations/xtech2006/javascript/ 를 참조해 주세요.

JavaScript 멀티스레딩(일부 제한 있음)이 여기에 있습니다.Google은 Gears를 위한 워커를 구현했으며 워커는 HTML5에 포함되어 있습니다.대부분의 브라우저는 이미 이 기능을 지원하고 있습니다.

작업자와 주고받는 모든 데이터는 직렬화/복사되므로 데이터의 스레드 안전성이 보장됩니다.

자세한 내용은 다음을 참조하십시오.

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

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

전통적으로 JS는 짧고 빠르게 실행되는 코드 조각들을 위해 고안되었습니다.주요 계산이 진행 중인 경우 서버에서 실행한 것입니다. JS+라는 아이디어입니다.HTML 앱이 당신의 브라우저에서 오랫동안 실행되어 사소한 일을 하는 것은 터무니없었습니다.

물론, 지금 우리는 그것을 가지고 있다.그러나 브라우저가 따라잡으려면 다소 시간이 걸릴 것입니다.대부분의 브라우저는 싱글 스레드 모델 위주로 설계되어 있기 때문에 변경은 쉽지 않습니다.Google Gears 측에서는 백그라운드 실행을 격리하도록 요구함으로써 잠재적인 많은 문제를 야기합니다. 즉, DOM을 변경하지 않고(그것은 스레드 세이프가 아니기 때문에), 메인 스레드에 의해 생성된 오브젝트에 액세스하지 않습니다(ditto).제한적이긴 하지만 브라우저 설계를 단순화하고 경험이 부족한 JS 코더가 스레드를 만지작거리게 하는 데 수반되는 위험을 줄이기 때문에 가까운 장래에 가장 실용적인 설계가 될 것입니다.

@marcio:

왜 그것이 Javascript에서 멀티스레딩을 구현하지 않는 이유입니까?프로그래머들은 그들이 가지고 있는 도구로 그들이 원하는 모든 것을 할 수 있다.

따라서 다른 웹 사이트를 열 때마다 브라우저가 크래시되는 오용하기 쉬운 툴은 제공하지 않도록 합시다.이것을 간단하게 실장하면, IE7의 개발중에 MS에 많은 골칫거리를 안겨준 영역에 곧바로 들어갈 수 있습니다.추가 기능 작성자는 스레드 모델을 빠르게 조작해, 프라이머리 스레드의 오브젝트의 라이프 사이클이 변경되었을 때에 숨겨진 버그가 판명되었습니다.좋지 않습니다. IE용 멀티 스레드 ActiveX 애드온을 쓰고 있다면 영역별로 제공되고 있습니다.그 이상으로 진행할 필요는 없습니다.

이 결정의 근거는 모르겠지만 set Timeout을 사용하여 멀티 스레드 프로그래밍의 이점을 시뮬레이션할 수 있다는 것은 알고 있습니다.여러 프로세스가 동시에 작업을 수행하는 것처럼 착각할 수 있지만, 실제로는 모든 것이 하나의 스레드에서 발생합니다.

기능에서 약간의 작업을 수행한 후 다음과 같은 전화를 걸면 됩니다.

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

UI 업데이트, 애니메이션 이미지 등 기타 필요한 작업은 기회가 있을 때 수행합니다.

언어가 멀티스레딩을 지원하지 않는 이유 또는 브라우저의 JavaScript 엔진이 멀티스레딩을 지원하지 않는 이유입니까?

첫 번째 질문에 대한 답변은 브라우저의 JavaScript는 샌드박스에서 머신/OS에 의존하지 않는 방법으로 실행되도록 되어 있기 때문에 멀티스레딩 지원을 추가하면 언어가 복잡해지고 OS와 너무 밀접하게 관련지어집니다.

Node.js 10.5+는 실험 기능으로 워커 스레드를 지원합니다( --experimental-worker 플래그를 활성화하여 사용할 수 있습니다).https://nodejs.org/api/worker_threads.html

규칙은 다음과 같습니다.

  • I/O 바운드 ops를 실행할 필요가 있는 경우는, 내부 메카니즘(콜백/약속/비동기 대기)을 사용합니다.
  • CPU 바인드 ops를 실행할 필요가 있는 경우는, 워커 스레드를 사용합니다.

워커 스레드는 긴 수명 스레드입니다.즉, 백그라운드스레드를 생성하여 메시지 전달을 통해 그 스레드와 통신합니다.

그렇지 않으면 익명 함수로 CPU 부하가 높은 경우 워커 스레드 주위에 구축된 작은 라이브러리를 https://github.com/wilk/microjob,로 이동할 수 있습니다.

매트 B가 말한 것처럼, 그 질문은 매우 명확하지 않다.언어로 멀티스레딩 지원에 대해 질문하는 경우: 현재 브라우저에서 실행 중인 애플리케이션의 99.999%에는 필요하지 않기 때문입니다.꼭 필요한 경우 window.setTimeout 사용 등 회피책이 있습니다.

일반적으로 멀티스레딩은 매우, 매우, 매우, 매우, 매우(불변의 데이터만 사용하는 등) 특별한 제한을 두지 않는 한 올바르게 실시하기 어렵습니다.

인텔은 최근 GDC 2012에서 소개된 Javascript의 멀티스레딩에 대한 오픈소스 연구를 진행하고 있다.동영상 링크입니다.연구진은 주로 인텔 칩셋과 윈도 OS에 초점을 맞춘 OpenCL을 사용했다.이 프로젝트는 RiverTrail이라는 코드명으로 GitHub에서 사용할 수 있습니다.

기타 유용한 링크:

웹 애플리케이션을 위한 컴퓨팅 고속도로 구축

현재 일부 브라우저는 멀티스레딩을 지원합니다.필요한 경우 특정 라이브러리를 사용할 수 있습니다.예를 들어, 다음 자료를 보십시오.

  • https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers (백그라운드 스레드 지원)

  • https://keithwhor.github.io/multithread.js/ (라이브러리).

Javascript는 단일 스레드 언어입니다.즉, 1개의 콜스택과 1개의 메모리히프가 있습니다예상대로 코드를 순서대로 실행하고 다음 순서로 진행하기 전에 부분 코드 실행을 완료해야 합니다.동기적이긴 하지만 가끔은 해로울 수도 있어요예를 들어, 함수가 실행되는 데 시간이 걸리거나 대기해야 하는 경우 그 사이에 모든 것이 정지됩니다.

멀티스레딩을 지원하지 않는 것이 실장입니다.현재 Google Gears는 외부 프로세스를 실행함으로써 어떤 형태로든 동시성을 사용할 수 있는 방법을 제공하고 있지만, 그것이 전부입니다.

구글이 오늘 출시하기로 한 새 브라우저(구글 크롬)는 진행 중인 코드를 분리해 병렬로 실행한다.

물론 핵심 언어는 Java와 같은 지원을 할 수 있지만, Erlang의 동시성 같은 것에 대한 지원은 거의 없다.

제가 들은 바로는 구글 크롬은 멀티스레드 자바스크립트를 가지고 있기 때문에 "현재 구현"의 문제입니다.

스레드 동기화에 대한 적절한 언어 지원이 없으면 새로운 구현을 시도하는 것조차 의미가 없습니다. 어플리케이션(ExtJ를 사용하는 것 은 예기치 크래쉬 할 , 「JS」(「ExtJ」)가 , 「ExtJ」)가 없어집니다.synchronized키워드나 이와 비슷한 것을 사용하면, 올바르게 동작하는 새로운 프로그램을 작성하는 것 또한 매우 어렵거나 심지어 불가능할 수 있습니다.

사실 멀티스레딩은 언어 자체와 관련이 없습니다.이것은 의 멀티스레드 Javascript 엔진입니다.NET. 멀티 스레드 시나리오에서 꽤 잘 작동합니다.C# 런타임과 통합되어 모든 동기 로직이 C#과 유사합니다.태스크를 시작/대기/대기할 수 있으며 스레드를 시작할 수 있습니다.자물쇠도 달 수 있어요.다음 예시는 의 Javascript 구문을 사용한 병렬루프를 나타내고 있습니다.NET 런타임

https://github.com/koculu/topaz

var engine = new TopazEngine();
engine.AddType(typeof(Console), "Console");
topazEngine.AddType(typeof(Parallel), "Parallel");
engine.ExecuteScript(@"
var sharedVariable = 0
function f1(i) {
    sharedVariable = i
}
Parallel.For(0, 100000 , f1)
Console.WriteLine(`Final value: {sharedVariable}`);
");

이 밖에도 마이크로소프트는 멀티스레딩 지원 Node.js 클론인 Napa.js에 대해 연구하고 있습니다.

https://github.com/microsoft/napajs

HTML5에서 가져온 웹워커를 사용하여 javascript를 통한 멀티스레딩이 확실하게 가능합니다.

웹워커와 표준 멀티스레딩 환경의 주요 차이점은 메모리 리소스가 메인 스레드와 공유되지 않고 오브젝트에 대한 참조가 스레드에서 다른 스레드로 표시되지 않는다는 것입니다.스레드는 메시지를 교환함으로써 통신하므로 이벤트 구동 설계 패턴에 따라 동기 및 동시 메서드 호출 알고리즘을 구현할 수 있습니다.

스레드 간 프로그래밍을 구조화할 수 있는 많은 프레임워크가 존재하며, 그중에서도 동시 프로그래밍을 지원하는 OOP js 프레임워크인 OODK-Js가 있습니다. https://github.com/GOMServices/oodk-js-oop-for-js

그러나 eval 함수를 사용하여 동시성을 SOME EXTENT로 가져올 수 있습니다.

/* 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;
    }
}

언급URL : https://stackoverflow.com/questions/39879/why-doesnt-javascript-support-multithreading

반응형