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


269

향후 버전에서 수정 될 현재 브라우저에 대한 의도적 인 설계 결정 또는 문제입니까?


3
웹 워커 / 워커 스레드에 대한 정보 는 JavaScript 및 스레드 질문에 대한 답변을 참조하십시오 .
Sam Hasler

115
안녕하십니까, Google 직원입니다. 여기에있는 모든 내용의 날짜가 매우 오래된 것 같습니다 (이 질문은 5 년 전에 요청 된 것입니다). 웹 브라우저는 요청을 받았을 때 어느 정도 멀티 스레딩 기능을 제공합니다. 웹 작업자를 살펴보십시오. msdn.microsoft.com/en-us/hh549259.aspx
ArtOfWarfare

2
Multithread.js는 웹 워커를 감싸고 JS에서 쉽게 멀티 스레딩을 허용합니다. iOS Safari를 포함한 모든 새 브라우저에서 작동합니다. :)
kwh

답변:


194

브라우저의 JavaScript 인터프리터는 단일 스레드 (AFAIK)이므로 JavaScript는 멀티 스레딩을 지원하지 않습니다. Chrome에서도 단일 웹 페이지의 JavaScript가 동시에 실행되지 않도록하면 기존 웹 페이지에서 대규모 동시성 문제가 발생할 수 있습니다. 모든 Chrome은 여러 구성 요소 (다른 탭, 플러그인 등)를 별도의 프로세스로 분리하지만 JavaScript 스레드가 두 개 이상인 단일 페이지를 상상할 수는 없습니다.

그러나 제안 된대로 setTimeout일정과 "가짜"동시성을 허용하기 위해 사용할 수 있습니다 . 이로 인해 브라우저는 렌더링 스레드를 다시 제어 setTimeout하고 지정된 밀리 초 후에 제공된 JavaScript 코드를 시작합니다 . 뷰포트 (조회 한 것)가 작업을 수행하는 동안 새로 고치도록하려는 경우에 매우 유용합니다. 예를 들어 좌표를 반복하고 그에 따라 요소를 업데이트하면 시작 및 끝 위치를 볼 수 있으며 그 사이에는 아무것도 없습니다.

우리는 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/를 확인 하십시오.


73
나는 결코 구현 이 너무 좁은 비전 이라고 생각 합니다. 웹 응용 프로그램은 결국 진정한 멀티 스레드가 될 수 있습니다 (웹 응용 프로그램이 지배적이며 하드웨어가 더 병렬화됨에 따라 논리적 일뿐입니다). 보시다시피 JavaScript는 웹 개발의 사실상의 언어이기 때문에 결국 멀티 스레딩을 지원하거나 다른 것으로 교체해야합니다.
devios1

6
결코 너무 대담한 진술은 아닙니다 :) 그러나 나는 여전히 진정한 멀티 스레드 자바 스크립트의 장점이 가까운 미래에 실현 가능하지 않다고 생각합니다.)
Kamiel Wanrooij

5
웹 워커는 스레드 모델보다 프로세스 모델을 통해 더 동시 적이라고 주장합니다. 웹 작업자는 메시지 전달을 통신 수단으로 사용하며 이는 다중 스레드 응용 프로그램의 '일반적인'동시성 문제에 대한 훌륭한 솔루션입니다. 그들이 실제로 메인 페이지와 동일한 객체에서 동시에 작동 할 수 있는지 확실하지 않습니다. 내가 아는 한 DOM에 액세스 할 수 없습니다. 그러나 이것의 대부분은 의미 론적이지만 웹 작업자는 모든 의도와 목적에 유망합니다.
Kamiel Wanrooij 2016 년

어려움 당신이 모든 추가 가능성을 생각한다면 확실하지 않은 추가 가능성보다 더 큰 방법이 있습니다 . 특히 webgl이 게임이나 그래픽 시각화에서 사용되는 경우를 생각합니다. 예를 들어 Google지도의 새로운 3D 버전을 고려하십시오. 많은 3D 모델이있는 도시에서 내 집은 많은 집을 렌더링해야 할 때 모든 것을로드하는 데 ~ 2 분이 필요합니다. 특정 각도에서 그래픽 카드 나 네트워크가 모두 작동하지 않습니다. 그러나 8 개 프로세서 중 1 개는 100 %입니다. 이 예제에서 볼 수 있듯이 멀티 스레딩은 fps 측면에서도 큰 관심사입니다. youtube.com/watch?v=sJ2p982cZFc
Scindix

25

JavaScript 멀티 스레딩 (일부 제한 사항)이 있습니다. Google은 Gears 작업자를 구현했으며 HTML5에 작업자가 포함되었습니다. 대부분의 브라우저는이 기능에 대한 지원을 이미 추가했습니다.

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

자세한 내용은 다음을 읽으십시오.

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

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


8
그러나 다중 스레드보다는 다중 프로세스 접근 방식이 아닌가? 스레드는 단일 힙 내에서 작동하는 것으로 알려져 있습니다.
beefeather

1
@beefeather, 그건 사실이야. 프로세스 접근 방식에 가깝습니다.

23

전통적으로 JS는 짧고 빠르게 실행되는 코드 조각을위한 것이 었습니다. 주요 계산을 수행 한 경우 서버 에서 수행했습니다. 브라우저에서 오랫동안 실행 된 JS + HTML 은 사소한 일을하지 않습니다.

물론, 지금 우리는 그것을 가지고 있습니다. 그러나 브라우저가 따라 잡는 데는 약간의 시간이 걸립니다. 대부분은 단일 스레드 모델을 중심으로 설계되었으며 변경하기는 쉽지 않습니다. Google Gears는 백그라운드 실행이 분리되어 DOM (스레드에 안전하지 않기 때문에)을 변경하지 않고 메인 스레드 (ditto)로 생성 된 개체에 액세스하지 않아도되므로 많은 잠재적 인 문제를 회피합니다. 제한적이지만 브라우저의 디자인을 단순화하고 경험이 부족한 JS 코더가 스레드로 엉망이되는 위험을 줄임으로써 가까운 장래에 가장 실용적인 디자인 일 것입니다 ...

@marcio :

Javascript에서 멀티 스레딩을 구현하지 않는 이유는 무엇입니까? 프로그래머는 원하는 도구를 사용하여 원하는대로 할 수 있습니다.

따라서 오용 하기 쉬운 도구를 제공하지 마십시오. 내가 연 다른 모든 웹 사이트에서 브라우저가 다운됩니다. 이것을 순진하게 구현하면 IE7 개발 중에 MS가 너무 많은 두통을 일으킨 영역으로 곧바로 들어올 수 있습니다. 추가 기능 작성자는 스레딩 모델에서 빠르고 느슨하게 재생되어 기본 스레드에서 객체 수명주기가 변경되면 숨겨진 버그가 발생했습니다. . 나쁜. IE 용 멀티 스레드 ActiveX 애드온을 작성하는 경우 영역과 함께 제공되는 것 같습니다. 그 이상으로 나아가 야한다는 의미는 아닙니다.


6
"이것은 경험이 부족한 JS 코더를 허용하는 데 관련된 위험을 줄입니다." 프로그래머는 원하는 도구를 사용하여 원하는대로 할 수 있습니다. 좋고 나쁘면 문제입니다. Chrome 프로세스 모델을 사용하면 다른 응용 프로그램에도 영향을 미치지 않습니다. :)
Marcio Aguiar

3
@ Shog9- "오용하기 쉬운 [프로그래머] 도구를 사용하지 마십시오. 열려있는 다른 모든 웹 사이트에서 브라우저가 다운 될 수 있습니다." - 뭐? 동일한 논리에 의해 언어에 멀티 스레딩이 없어야합니다. 언어를 제공하면 다른 모든 프로그램에서 충돌을 일으킬 수 있기 때문입니다. 그런 식으로 작동하지 않는 한. 스레딩은 대부분의 언어로 존재하며 대부분의 초보자 프로그래머는 손대지 않으며 프로덕션에 넣지 않은 대부분의 응용 프로그램과 인기가 없거나 널리 사용되지 않는 앱입니다.
ArtOfWarfare

11

이 결정에 대한 이론적 근거는 모르지만 setTimeout을 사용하여 멀티 스레드 프로그래밍의 이점을 시뮬레이션 할 수 있다는 것을 알고 있습니다. 실제로는 모든 프로세스가 하나의 스레드에서 발생하지만 여러 프로세스가 동시에 작업을한다는 환상을 줄 수 있습니다.

함수가 약간의 작업을 수행하도록 한 다음 다음과 같이 호출하십시오.

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

그리고 UI 업데이트, 애니메이션 이미지 등과 같은 기타 필요한 작업은 기회가있을 때 발생합니다.


대부분의 경우 loop내부 를 사용 하고 setTimeout싶지만 분명히 작동하지 않습니다. 그런 일을 했습니까, 아니면 해킹을 했습니까? 예를 들어 1000 요소 배열의 setTimeout경우 첫 번째 루프 스루 및 인쇄 요소 0..499, 두 번째 루프 스루 및 인쇄 요소 가되도록 두 호출 내부에 두 개의 for 루프를 사용할 것으로 예상됩니다 500..999.
benjaminz

일반적으로 기술은 상태를 저장하고 계속하는 것입니다. 예를 들어, 0에서 1000을 인쇄하고 0에서 499를 인쇄 한 다음 인수 500으로 setTimeout 트릭을 수행 할 수 있습니다. 내부 코드는 인수 (500)을 가져 와서 루프를 시작하는 것으로 알고 있습니다.
Eyal

8

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

첫 번째 질문에 대한 답변은 브라우저의 JavaScript가 샌드 박스와 머신 / OS 독립적 인 방식으로 실행되도록되어 있으며 멀티 스레딩 지원을 추가하면 언어가 복잡해지고 언어가 OS에 너무 밀접하게 연결될 수 있습니다.


6

Node.js 10.5+는 작업자 스레드 를 실험 기능으로 지원 합니다 ( --experimental-worker 플래그가 활성화 된 상태에서 사용할 수 있음). https://nodejs.org/api/worker_threads.html

따라서 규칙은 다음과 같습니다.

  • I / O 바운드 작업 을 수행해야하는 경우 내부 메커니즘을 사용하십시오 (일명 콜백 / 프로 미스 / async-await).
  • CPU 바운드 ops 를 수행해야하는 경우 작업자 스레드를 사용하십시오.

워커 스레드는 수명이 긴 스레드이므로 백그라운드 스레드를 생성 한 다음 메시지 전달을 통해 통신합니다.

그렇지 않으면 익명 함수로 과도한 CPU로드를 실행해야하는 경우 작업자 스레드를 중심으로 구축 된 작은 라이브러리 인 https://github.com/wilk/microjob 을 사용할 수 있습니다 .


4

matt b가 말했듯이 질문은 분명하지 않습니다. 언어로 멀티 스레딩 지원을 요청한다고 가정하면 : 현재 브라우저에서 실행중인 응용 프로그램의 99.999 %가 필요하지 않기 때문입니다. 실제로 필요한 경우 해결 방법이 있습니다 (예 : window.setTimeout 사용).

일반적으로 멀티 스레딩은 불변의 데이터 만 사용하는 것과 같은 추가 제한을 두지 않는 한 올바르게 달성하기가 매우 어렵습니다.


3

인텔은 Javascript의 멀티 스레딩에 대한 오픈 소스 연구를 수행하고 있으며 최근 GDC 2012에서 소개되었습니다. 비디오 링크는 다음과 같습니다. . 이 연구 그룹은 OpenCL을 사용했으며 주로 Intel 칩셋 및 Windows OS에 중점을 둡니다. 이 프로젝트의 이름은 RiverTrail이며 코드는 GitHub에서 사용할 수 있습니다.

더 유용한 링크들 :

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



1

멀티 스레딩을 지원하지 않는 구현입니다. 현재 Google Gears는 외부 프로세스를 실행하여 어떤 형태의 동시성을 사용할 수있는 방법을 제공하고 있습니다.

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

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


1

자바 스크립트는 단일 스레드 언어입니다. 이것은 하나의 호출 스택과 하나의 메모리 힙을 가지고 있음을 의미합니다. 예상대로 코드를 순서대로 실행하고 다음 코드로 넘어 가기 전에 조각 코드 실행을 완료해야합니다. 동 기적이지만 때로는 해로울 수 있습니다. 예를 들어, 함수가 실행하는 데 시간이 걸리거나 무언가를 기다려야하는 경우 그 동안 모든 것이 고정됩니다.


0

Chrome에서 멀티 스레드 자바 스크립트를 사용한다고 들었을 때 "현재 구현"문제입니다.


0

스레드 동기화에 대한 적절한 언어 지원이 없으면 새로운 구현을 시도하는 것도 의미가 없습니다. 기존의 복잡한 JS 앱 (예 : ExtJS를 사용하는 것)은 예기치 않게 충돌 할 가능성이 높지만 synchronized키워드 나 이와 유사한 기능이 없으면 올바르게 작동하는 새 프로그램을 작성하는 것이 매우 어렵거나 불가능할 수도 있습니다.


-1

그러나 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;
    }
}

-2

HTML5로 가져온 웹 워커를 사용하면 자바 스크립트를 사용한 멀티 스레딩이 가능합니다.

웹 작업자와 표준 멀티 스레딩 환경의 주요 차이점은 메모리 리소스가 기본 스레드와 공유되지 않으며 객체에 대한 참조가 한 스레드에서 다른 스레드로 표시되지 않는다는 것입니다. 스레드는 메시지를 교환하여 통신하므로 이벤트 중심 디자인 패턴에 따라 동기화 및 동시 메서드 호출 알고리즘을 구현할 수 있습니다.

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


5
메모리 공유는 별도의 프로세스 (예 : fork () vs exec ())와 반대되는 스레드의 정확한 정의입니다. 스레드는 객체를 공유 할 수 있으며 프로세스는 IPC를 사용해야합니다. 웹 워커는 멀티 스레딩이 아닙니다.
felixfbecker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.