2009-02-28 5 views

답변

50

이것은 흥미로운 질문입니다.

비동기 프로그래밍은 주로 단일 스레드, 즉 "하나의 연속 실행 스레드를 따르는"프로그래밍의 패러다임입니다.

자바 스크립트를 참조하므로 웹 브라우저 환경에서 언어를 토론 할 수 있습니다. 웹 브라우저는 각 창에서 자바 스크립트 실행의 단일 스레드를 실행하고 이벤트 (onclick = "someFunction()") 및 네트워크 연결 (예 : xmlhttprequest 호출)을 처리합니다.

<script> 
function performRequest() { 
    xmlhttp.open("GET", "someurl", true); 
    xmlhttp.onreadystatechange = function() { 
    if (xmlhttp.readyState == 4) { 
     alert(xmlhttp.responseText); 
    } 
    } 
    xmlhttp.send(sometext); 
} 
</script> 
<span onclick="performRequest()">perform request</span> 

(이는 개념의 데모 용으로 만 사용됩니다.

비동기 방식으로 모든 작업을 수행하기 위해 제어 스레드에는 '주 루프'가 있습니다. 메인 루프는 다음과 같은 종류의 외모 :

while (true) { 
    event = nextEvent(all_event_sources); 
    handler = findEventHandler(event); 
    handler(event); 
} 

이가 '바쁜 루프'가 아니라는 것을 주목하는 것이 중요하다. 이것은 활동이 일어날 때까지 기다리는 것과 같은 종류입니다. 활동은 사용자로부터 입력 (마우스 움직임, 버튼 클릭, 타이핑)되거나 네트워크 활동 (서버의 응답) 일 수 있습니다.

findEventHandler()을 스팬 태그에 onclick 이벤트를 발견 할

스팬에서 사용자가 클릭하는은 buttonClicked 이벤트가 생성 될
  1. 그래서, 위의 예에서

    , 및 그 핸들러 것 이벤트와 함께 불렀다.

  2. xmlhttp 요청을 만들면 all_event_sources 이벤트 소스 목록에 추가됩니다.
  3. performRequest() 함수가 반환 된 후 mainloop은 응답을 기다리는 nextEvent() 단계에서 대기합니다. 이 시점에서 처리되는 추가 이벤트가 '차단'되지 않습니다.
  4. 데이터가 원격 서버에서 돌아 오면 nextEvent()는 네트워크 이벤트를 반환하고 onreadystatechange() 메서드 인 이벤트 처리기가 발견되어 해당 메서드가 호출되고 alert() 대화 상자가 실행됩니다.

alert()은 차단 대화 상자입니다. 대화 상자가 열려있는 동안에는 더 이상의 이벤트를 처리 할 수 ​​없습니다. 그것은 웹 페이지의 자바 스크립트 모델의 편심입니다. 우리는 쉽게 사용할 수있는 메서드를 가지고있어서 해당 페이지의 컨텍스트 내에서 추가 실행을 차단합니다. 특히 자바 스크립트에 대한

+0

대답의 편집을 제안하십시오 "그것은 가치가 없습니다." 은 과 다른 "noTing의 가치가 있습니다"라고 생각하는 은 귀하의 의도라고 생각합니다. 독자들에게 혼란을 피하기 위해. – MadMurf

+0

@MadMurf : 나는 그것을 또한 알아 차렸다. – mpen

+0

>> 비동기 프로그래밍은 원칙적으로 단일 스레드 인 프로그래밍 패러다임입니다. << - 여기에 과소 평가를하려는 것은 아니지만이 진술이 사실인지 어떻게 볼 수는 없습니다. 비동기 프로그래밍은 스레드에 대해 아무 것도 말하지 않고, 단일 대 복수 대가 될 수 있습니까? – Lee

15

자바 스크립트 모델은 싱글 스레드입니다. 비동기 호출은 이 아니며 새 스레드 인이 아니라 기존 스레드를 인터럽트합니다. 커널의 인터럽트와 유사합니다.

예 단일 스레드로 비동기 호출을하는 것이 좋습니다. 그것에 대해 생각하는 방법은 다음과 같습니다. 단일 스레드 내에서 함수를 호출하면 현재 메소드의 상태가 스택 (예 : 로컬 변수)에 푸시됩니다. 서브 루틴이 호출되고 결국 반환되어 원래 상태가 스택에서 팝 아웃됩니다.

비동기 콜백에서는 동일한 일이 발생합니다! 차이점은 서브 루틴이 서브 루틴을 호출하는 현재 코드가 아닌 시스템에 의해 호출된다는 것입니다.

+1

>> 비동기 호출이 새 스레드가 아닙니다. << - 이것은 잘못된 문이라고 생각합니다. JS가 새로운 스레드로 XHR 요청을 처리하는 것을 막는 것에 대해서는 전혀 알지 못합니다. 나는 당신이 새로운 쓰레드가 스펙에 의해 보장되거나 제안되지 않는다는 것을 의미한다고 생각하지만, 확실히 시스템에 의해 구현되는 방법 일 수있다. – Lee

4

많은 GUI 응용 프로그램에서 비동기 호출 (예 : Java의 invokeLater)은 GUI 스레드 대기열에 Runnable 객체를 추가하기 만합니다. GUI 스레드가 이미 생성되었으며 새 스레드를 생성하지 않습니다. 그러나 스레드는 비동기식 시스템의 경우에도 엄격하게 요구되지 않습니다. 예를 들어 libevent는 select/poll/kqueue 등을 사용하여 비 블로킹 호출을 소켓에 생성 한 다음 코드에 대한 콜백을 스레드없이 실행합니다.

5

몇 노트 :

XMLHttpRequest의는 기본적으로 비 차단합니다. send() 메서드는 요청이 기본 네트워크 스택으로 릴레이 된 직후에 반환됩니다. 서버로부터의 응답은 다른 우수한 응답에 의해 논의 된대로 이벤트 루프에서 콜백 호출을 스케줄합니다.

새 스레드가 필요하지 않습니다. 기본 소켓 API는 Java에서 java.nio.channels과 유사하게 선택할 수 있습니다.

open() 내지 제 false 파라미터로 전달하여 동기XMLHttpRequest 객체를 구성하는 것이 가능하다. 이로 인해 서버에서 응답을받을 때까지 send() 메서드가 차단되어 네트워크 대기 시간이 만료되고 네트워크 시간 초과가 발생할 때까지 브라우저를 정지시킬 수 있습니다. 이것은 나쁜 일입니다.

Firefox 3.5는 Worker 클래스의 정직 - 대 - 신 다중 스레드 JavaScript를 소개합니다. 백그라운드 코드는 완전히 다른 환경에서 실행되며 이벤트 루프에서 콜백을 예약하여 브라우저 창과 통신합니다.

+0

당신이 '서버로부터의 응답이 이벤트 루프에서 콜백 호출을 스케줄 할 것'이라고 말했을 때, 어떤 스레드가 이벤트 루프에 이벤트를 넣어 콜백을 호출 할 것인가? – Yiling

+1

@Yiling 이벤트는 자바 스크립트를 실행하는 스레드가 아니라 브라우저 내부의 I/O 스레드에 의해 생성됩니다. – Matthew

2

아니요, 하나 이상의 스레드가 관련됩니다.

비동기 호출은 작업을 수행하기 위해 다른 스레드를 시작하거나 이미 실행중인 다른 스레드의 큐에 메시지를 게시 할 수 있습니다. 호출자가 계속되고 호출 수신자가 메시지를 처리하면 호출자가 다시 호출합니다.

이 컨텍스트에서 동기식 호출을 수행하려면 메시지를 게시하고 콜백이 발생하기를 기다려야합니다.

요약하면 : 두 개 이상의 스레드가 관련되지만 반드시 새 스레드를 생성하지는 않습니다.

2

자바 스크립트에 대해서는 잘 모르겠지만, 예를 들어 Windows Forms 세계에서는 다중 스레드없이 비동기 호출을 할 수 있습니다. 이것은 Windows Message Pump가 작동하는 방식과 관련이 있습니다. 기본적으로 Windows Forms 응용 프로그램은 Windows가 이벤트에 대해 알리는 메시지를 배치하는 메시지 큐를 설정합니다. 예를 들어, 마우스를 움직이면 메시지는 해당 대기열에 배치됩니다. Windows Forms 응용 프로그램은 끝이없는 루프에서 처리되는 모든 메시지를 소비합니다. 각 메시지에 포함 된 내용에 따라 창을 이동하거나 다시 그리거나 심지어 사용자 정의 메서드를 호출 할 수도 있습니다. 메서드에 대한 호출은 대리자에 의해 식별됩니다. 응용 프로그램이 대기열에서 대리자 인스턴스를 찾으면 위임자가 참조하는 메소드를 기꺼이 호출합니다.

새로운 무언가를 만들지 않고 무언가를하고 비동기 작업을 생성하려는 메서드에 있다면 Control.BeginInvoke 메서드를 사용하여 대리자 인스턴스를 큐에 배치하기 만하면됩니다. 자, 이것은 실제로 다중 쓰레드가 아니지만 큐에 아주 작은 작업을 던지면 다중 쓰레드처럼 보일 것입니다. 반면에 실행하는 데 시간이 많이 걸리는 메서드를 제공하면 메서드가 완료 될 때까지 응용 프로그램이 고정됩니다.이 메서드는 무엇인가하고 있어도 걸린 응용 프로그램처럼 보입니다.

관련 문제