2

http://krondo.com/?p=1209 또는 Does an asynchronous call always create/call a new thread?을 읽은 후에도 본질적으로 단일 스레드 시스템에서 비동기 호출을 제공하는 방법에 대해서는 여전히 혼란 스럽습니다. 나는 지금까지 나의 이해를 설명하고 나의 의심을 지적 할 것이다.단일 스레드로 비동기 처리

내가 읽은 예제 중 하나는 요청의 비동기 처리를 제공하는 TCP 서버를 설명하는 것이 었습니다. get(Callback c)이며 나중에 콜백이 호출됩니다. 자, 여기 내 첫 번째 문제 - 우리는 이미 두 개의 시스템, 하나의 서버와 하나의 클라이언트가 있습니다. 이것은 제가 의미하는 바가 아닙니다. 서버에 하나, 클라이언트 측에 적어도 하나씩 두 개의 스레드가 있습니다.

다른 예제는 JavaScript로 Node.js 인 단일 스레드 비동기 시스템에서 가장 눈에 띄는 예제입니다. 내가 어쩌면, 자바의 관점에서 생각하고, 내 머리를 통해 얻을 수있는 것은 이것이다 : 나는 아래의 코드를 실행하면 (잘못된, 아마 잔인한 구문에 대한 사과) :

function foo(){ 
    read_file(FIle location, Callback c) //asynchronous call, does not block 
    //do many things more here, potentially for hours 
} 

호출이 파일이 실행 (STH) 및 읽기 반환, 내 함수의 나머지 부분을 실행할 수 있습니다. 하나의 스레드 즉, 내 함수를 실행하는 스레드가 있기 때문에 동일한 스레드 (내 물건을 실행하는 유일한 스레드)가 디스크에서 바이트를 읽는 방법은 어떨까요?

기본적으로, 본질적으로 단일 스레드이며 일을 더 작은 것들로 나눌 수있는 일종의 라운드 로빈 스케줄러처럼 작동하는 기본 메커니즘이 누락 된 것처럼 보입니다. 또는 다중 골치 아픈 구성 요소를 호출 할 수 있습니다. 스레드를 생성하고에서 파일을 읽으십시오.

모든 의견에 대해 미리 감사 드리며 실수를 지적하십시오.

업데이트 : 답장을 보내 주셔서 감사합니다. 이것 좀 도와 또한 좋은 소스는 여기에 있습니다 :

  1. http://www.html5rocks.com/en/tutorials/async/deferred/
  2. http://lostechies.com/johnteague/2012/11/30/node-js-must-know-concepts-asynchrounous/
  3. http://www.interact-sw.co.uk/iangblog/2004/09/23/threadless (.NET)
  4. http://ejohn.org/blog/how-javascript-timers-work/ (타이머 내장)
  5. http://www.mobl-lang.org/283/reducing-the-pain-synchronous-asynchronous-programming/
+0

이 수도 있고 암시 적으로 보류중인 작업에 의해 시작 배경 스레드 수 있지만,이 작업 자체를 시작 자바 스크립트 코드에 완전히 불투명와 무관입니다하지 않을 수 있습니다. 웹 브라우저 (또는 NodeJS, FTM)의 JavaScript 스레드의 핵심 이벤트 루프는 단일 스레드입니다. – Noseratio

답변

2

진짜 대답은 그것이 당신이 "단일 스레드 ".

멀티 태스킹에는 협동 및 인터럽트 구동이라는 두 가지 방법이 있습니다. Cooperative는 다른 StackOverflow 항목에서 설명한 것과 같이 루틴이 프로세서의 소유권을 명시 적으로 포기해야 다른 작업을 수행 할 수 있습니다. 이벤트 중심 시스템은 종종 이러한 방식으로 설계됩니다. 장점은 관리하기가 훨씬 쉽고 한 번에 하나의 코드 덩어리 만 실행되기 때문에 데이터 액세스 충돌의 위험을 피할 수 있다는 것입니다. 단점은 한 번에 한 가지만 수행되기 때문에 모든 것이 상당히 빠르게 실행되도록 설계되거나 (yield() 호출과 같이 명시 적 일시 중지를 통해) 청크로 분할되거나 시스템이 표시되어야한다는 것입니다 해당 이벤트가 완전히 처리 될 때까지 고정합니다.

다른 접근법 (스레드 또는 프로세스)은 실행중인 코드 덩어리에서 프로세서를 적극적으로 제거하고 다른 작업이 진행되는 동안 프로세서를 일시 중지합니다.이것은 구현하기가 훨씬 더 복잡하고 공유 된 데이터 구조에 동시에 액세스 할 수있는 위험이 있기 때문에 코딩 작업에 더 많은주의를 기울이지 만 더 강력하고 올바르게 완료됩니다. 훨씬 강력하고 응답 성이 좋습니다.

예, 실제로 어떤 경우에도 관련된 스케줄러가 있습니다. 이전 버전에서 스케줄러는 이벤트가 도착할 때까지 (운영 체제 및/또는 런타임 환경 (암시 적으로 다른 스레드 또는 프로세스)에서 전달 될 때까지) 회전하고 다음 이벤트를 처리하기 전에 해당 이벤트를 전달합니다.

+0

그래서 Java 스크립트에서 디스크에서 파일을로드하는 호출은 처리 할 대기열에 배치 된 이벤트 또는 일련의 이벤트일까요? 그러나 그 이후로, 실제로는 하나의 쓰레드 만 존재할 수 있기 때문에, 실제로는 실행 쓰레드가 아닙니다. 큐의 이벤트를 잡아내는 주 루프 쓰레드입니다. 그래서, 메인 쓰레드가 이벤트를 당기는 일을하는 동안, 분명히 그 이벤트를 스케줄링하는 또 다른 스레드가 있어야합니다. 그 대기열에 넣는 거지? – Bober02

+0

저는 Javascript 사용자가 아니기 때문에 특별히 대답 할 수 없습니다. 하지만, 자바 스크립트가 실행되고있는 브라우저 나 다른 런타임 환경을 비롯하여 전체 운영체제가 뒤 따른다는 것을 기억하십시오. 자바 스크립트에서 자체 스레드/프로세스 시분할을 사용하고 자바 스크립트의 비동기 연산이 전달 될 수 있습니다 그들에게. – keshlam

0

JavaScript에서 생각하는 방식은 이벤트를 보유한 대기열이 있다는 것입니다. 오래된 Java 프로듀서/소비자 용어에는이 큐에서 물건을 뽑아 내고 현재 이벤트를 수신하기 위해 등록 된 모든 기능을 실행하는 단일 소비자 스레드가 있습니다. 비동기 호출 (AJAX 요청 완료), 시간 초과 또는 마우스 이벤트와 같은 이벤트가 발생하자마자 대기열로 푸시됩니다. 단일 "소비자"쓰레드는 큐에서 꺼내어 관심있는 함수를 찾아서 실행하고 현재 이벤트에 등록 된 모든 함수를 호출 할 때까지 다음 이벤트를 얻을 수 없습니다. 따라서 결코 완료되지 않는 핸들러가있는 경우 큐가 채워집니다. 이는 "차단됨"이라고합니다.

무언가가 대기열로 이동하는 이벤트를 생성하지만 이벤트 처리기 작성자는 이벤트가 처리된다는 것을 알고 있어야하므로 시스템에 스레드가 두 개 이상 있습니다 (하나 이상의 생성자와 소비자가 있음). 단일 스레드에서 단단한 루프로 들어가면 유일한 소비자 스레드를 잠그고 시스템을 응답하지 않게 만듭니다. 그래서 예에서

:

function foo(){ 
    read_file(location, function(fileContents) { 
     // called with the fileContents when file is read 
    }  
    //do many things more here, potentially for hours 
} 

귀하의 의견을 말한다 및 시간 잠재적으로 실행으로 당신이 할 경우 - 시간의 파일을 읽을 된 경우에도 발생하지 않습니다 된 FileContents을 처리하는 콜백을. foo()의 마지막}을 친다면 소비자 스레드는이 이벤트로 끝나고 파일 내용으로 등록 된 콜백을 실행할 다음 스레드를 처리 할 수 ​​있습니다.

HTH

관련 문제