비동기식, 비차 단식, 이벤트 기반 아키텍처의 차이점은 무엇입니까?


84
  1. 차이점은 무엇입니까?

    • 비동기 ,
    • 비 차단
    • 이벤트 기반 아키텍처?
  2. 뭔가가 될 수 모두 비동기비 차단 (및 이벤트 기반 )?

  3. 프로그래밍에서 가장 중요한 것은 비동기, 비 차단 및 / 또는 이벤트 기반 (또는 3 개 모두)일까요?

예제를 제공 할 수 있다면 좋을 것입니다.

이 질문은 비슷한 주제에 대한 훌륭한 StackOverflow 기사를 읽었 기 때문에 제기 되었지만 위의 질문에 대한 답변이 아닙니다.

답변:


91

비동기 비동기는 말 그대로 동기가 아님을 의미합니다. 이메일은 비동기 적입니다. 메일을 보내면 지금 응답을받을 수 없습니다. 그러나 그것은 비 차단이 아닙니다. 본질적으로 이것이 의미하는 것은 "구성 요소"가 즉시 응답을 기대하지 않고 서로에게 메시지를 보내는 아키텍처입니다. HTTP 요청은 동기식입니다. 요청을 보내고 응답을받습니다.

Non-Blocking 이 용어는 주로 IO와 함께 사용됩니다. 이것이 의미하는 바는 시스템 호출을 할 때 스레드를 잠자기 상태로 두지 않고 (높은 확률로) 어떤 결과를 가져도 즉시 반환된다는 것입니다. 예를 들어 비 차단 읽기 / 쓰기 호출은 그들이 할 수있는 모든 것을 반환하고 호출자가 호출을 다시 실행할 것으로 기대합니다. 예를 들어 try_lock은 비 차단 호출입니다. 잠금을 획득 할 수있는 경우에만 잠 깁니다. 시스템 호출의 일반적인 의미는 차단입니다. 읽기는 데이터가있을 때까지 대기하고 호출 스레드를 절전 모드로 전환합니다.

이벤트 기반 이 용어는 libevent에서 유래되었습니다. 비 차단 읽기 / 쓰기 호출 자체는 "언제"다시 전화해야하는지 (재시도) 알려주지 않기 때문에 쓸모가 없습니다. select / epoll / IOCompletionPort 등은 이러한 호출이 "흥미로운"데이터를 반환 할 것으로 예상되는 "언제"OS에서 알아 내기위한 다른 메커니즘입니다. libevent 및 기타 이러한 라이브러리는 다양한 OS에서 제공하는 이러한 이벤트 모니터링 기능에 대한 래퍼를 제공하고 운영 체제에서 실행되는 일관된 API를 제공합니다. 비 차단 IO는 이벤트 기반과 함께 사용됩니다.

나는이 용어들이 겹친다 고 생각합니다. 예를 들어 HTTP 프로토콜은 동기식이지만 비 차단 IO를 사용하는 HTTP 구현은 비동기식 일 수 있습니다. 다시 읽기 / 쓰기 / try_lock과 같은 비 차단 API 호출은 동기식 (즉시 응답 제공)이지만 "데이터 처리"는 비동기식입니다.


2
지속적인 폴링이 필요한 비 차단에 대한 좋은 점은 비동기가 푸시 기반 일 수 있습니다.
Alexander Torstling

즉각적인 응답을받는 것으로 synchronuous를 정의했지만 Google 동기식으로 모든 사전에서 '즉시 응답'이 아닌 '동시에 발생'으로 정의합니다.
IntelliData

4
이메일을 보내지 만 답변을 기대하지 않을 때 어떻게 차단됩니까? 응답을 기다리면서 내 일을 생각할 수 있습니다.
Koray Tugay

20

비동기 하드웨어에서 코드는 어떤 엔티티에 무언가를 요청하고 액션이 완료되는 동안 다른 일을 자유롭게 할 수 있습니다. 작업이 완료되면 엔티티는 일반적으로 어떤 방식 으로든 코드에 신호를 보냅니다. 비 차단 아키텍처는 코드가 관심을 가질 수있는 자발적으로 발생하는 작업을 기록하고 코드에서 이러한 작업이 발생했는지 묻도록 허용하지만 코드는 명시 적으로 해당 작업에 대해 물어볼 때만 이러한 작업을 인식합니다. 이벤트 기반 아키텍처는 이벤트가 자발적으로 발생할 때 코드에 긍정적으로 알립니다.

코드가 1,000 바이트를 수신하려는 직렬 포트를 고려하십시오.

차단 읽기 아키텍처에서 코드는 1,000 바이트가 도착하거나 포기하기로 결정할 때까지 대기합니다.

비동기 읽기 아키텍처에서 코드는 드라이버에게 1,000 바이트가 필요하다는 것을 알리고 1,000 바이트가 도착하면 알림을받습니다.

비 차단 아키텍처에서 코드는 언제든 도착한 바이트 수를 물어볼 수 있으며, 적합하다고 판단되면 그러한 데이터의 일부 또는 전부를 읽을 수 있지만, 모든 데이터가 도착했을 때 알 수있는 유일한 방법은 묻는 것입니다. 코드가 1000 번째 바이트가 도착했을 때 1/4 초 이내에 알아 내려면 1/4 초 정도마다 확인해야합니다.

이벤트 기반 아키텍처에서 직렬 포트 드라이버는 데이터가 도착할 때마다 애플리케이션에 알립니다. 드라이버는 응용 프로그램이 원하는 바이트 수를 알지 못하므로 응용 프로그램은 응용 프로그램이 원하는 것보다 작거나 큰 양에 대한 알림을 처리 할 수 ​​있어야합니다.


5

따라서 첫 번째와 두 번째 질문에 답하려면 :

비 차단은 사실상 비동기와 동일합니다. 호출을하면 나중에 결과를 얻을 수 있지만 그 동안 다른 작업을 수행 할 수 있습니다. 차단은 그 반대입니다. 여행을 계속하기 전에 전화가 돌아올 때까지 기다립니다.

이제 Async / Non-blocking 코드는 정말 환상적으로 들립니다. 하지만 경고의 말이 있습니다. 비동기 / 비 차단은 휴대폰과 같이 제한된 환경에서 작업 할 때 유용합니다. 제한된 CPU / 메모리를 고려하십시오. 코드가 어떤 식 으로든 UI 위젯에 반응해야하는 프런트 엔드 개발에도 좋습니다.

비동기는 모든 운영 체제가 작동해야하는 방식의 기본입니다. 백그라운드에서 작업을 수행하고 요청한 작업을 완료하면 코드를 깨우고 해당 호출이 실패하면 작동하지 않는다는 메시지를받습니다. 예외 또는 일종의 반환 코드 / 오류 개체에 의해 작동합니다.

코드가 응답하는 데 시간이 걸리는 무언가를 요청하는 시점에서 OS는 다른 작업으로 바쁠 수 있음을 알고 있습니다. 코드-프로세스, 스레드 또는 동등한 블록. 여러분의 코드는 네트워크 연결이 이루어지기를 기다리는 동안 또는 HTTP 요청의 응답을 기다리는 동안 또는 파일 읽기 / 쓰기를 기다리는 동안 OS에서 어떤 일이 벌어지고 있는지 전혀 알지 못합니다. 곧. 코드는 "간단히"마우스 클릭을 기다릴 수 있습니다. 그 당시 실제로 진행된 것은 OS가 메모리, I / O (키보드, 마우스, 디스크, 인터넷) 관리와 같이 OS가 찾고있는 "이벤트"를 원활하게 관리하고, 일정을 잡고, 이에 반응한다는 것입니다. 기타 작업, 장애 복구 등

운영 체제는 하드 코어입니다. 그들은 프로그래머에게 복잡한 비동기 / 비 차단 항목을 모두 숨기는 데 정말 능숙합니다. 이것이 바로 대부분의 프로그래머가 소프트웨어를 사용하여 오늘날의 위치에 도달 한 방법입니다. 이제 우리는 CPU 한계에 도달하고 있습니다. 사람들은 성능 향상을 위해 병렬로 작업을 수행 할 수 있다고 말합니다. 즉, 비동기 / 비 차단이 매우 유리한 일처럼 보이며 소프트웨어에서 요구하는 경우 동의 할 수 있습니다.

백엔드 웹 서버를 작성하는 경우주의해서 진행하십시오. 훨씬 저렴하게 수평으로 확장 할 수 있습니다. 넷플릭스 / 아마존 / 구글 / 페이스 북은이 규칙에 대한 명백한 예외입니다. 순전히 하드웨어를 덜 사용하는 것이 더 저렴하기 때문입니다.

비동기 / 비 차단 코드가 백엔드 시스템에서 악몽 인 이유를 말씀 드리겠습니다 ....

1) 생산성에 대한 서비스 거부가됩니다 ... 더 많이 생각해야하고 그 과정에서 많은 실수를합니다.

2) 반응 형 코드의 스택 추적은 해독 할 수 없게됩니다. 무엇을, 언제, 왜, 어떻게 호출했는지 알기 어렵습니다. 디버깅에 행운을 빕니다.

3) 당신은 어떻게 실패했는지에 대해 더 많이 생각해야합니다. 구세계에서는 한 번에 한 가지만했습니다.

4) 테스트하기가 더 어렵습니다.

5) 유지하기가 더 어렵습니다.

6) 고통 스럽습니다. 프로그래밍은 즐겁고 재미 있어야합니다. 마조히스트 만이 고통을 좋아합니다. 동시 / 반응 프레임 워크를 작성하는 사람들은 새디스트입니다.

그리고 네, 동기화와 비동기를 모두 작성했습니다. 99.99 개의 백엔드 애플리케이션이이 패러다임을 통해 얻을 수있는 동기식을 선호합니다. 프런트 엔드 앱에는 의심의 여지없이 반응 형 코드가 필요하며 항상 그랬습니다.

  1. 예, 코드는 비동기식, 비차 단식 및 이벤트 기반 일 수 있습니다.

  2. 프로그래밍에서 가장 중요한 것은 코드가 허용되는 시간 내에 작동하고 응답하는지 확인하는 것입니다. 그 핵심 원칙을 고수하면 잘못 될 수 없습니다.


** 업데이트 ** Go와 함께 플레이하고 채널과 go-routine을 살펴본 후, 언어 구조가 Sadist 프레임 워크 작성자의 모든 고통을 덜어주기 때문에 실제로 내 코드를 더 동시에 만드는 것을 좋아한다고 말해야합니다. 우리는 비동기 처리의 세계에서 "안전한 단어"를 가지고 있습니다. 이것이 바로 "Go!"입니다.
user924272

4

나에게 non-blocking은 스레드에서 작업의 예외가 다른 스레드의 실행에 의존하지 않고 특히 중요 섹션이 필요하지 않음을 의미합니다.

비동기는 예외가 호출자의 흐름 외부에서 발생하고 잠재적으로 무시됨을 의미합니다. 실행은 일반적으로 다른 스레드에서 발생합니다.

동시 데이터 읽기는 비 차단 (잠글 필요 없음)이지만 동기식입니다. 역으로 동기식으로 동시에 데이터를 쓰는 것은 차단 (배타적 잠금 필요)입니다. 기본 흐름의 관점에서 비 차단으로 만드는 방법은 쓰기를 비동기로 만들고 실행을 연기하는 것입니다.

이벤트의 개념은 다른 것입니다. 대략적으로 말하면 무언가가 발생하면 알림을 받는다는 의미입니다. 쓰기가 비동기 적으로 실행 된 경우 쓰기가 실행 된 후 시스템의 다른 부분에 알리기 위해 이벤트가 발생할 수 있습니다. 다른 부분은 이벤트에 응답합니다. 시스템은 구성 요소 (액터 모델을 생각해보십시오)간에 통신하는 유일한 방법으로 이벤트를 기반으로 만 구축 될 수 있지만 반드시 그럴 필요는 없습니다.

세 용어는 관련이 있지만 저에게는 다른 개념입니다. 그러나 사람들은 다소 상호 교환 가능한 방식으로 사용할 수 있습니다.


2

일반적으로 비 차단 아키텍처는 작업자 스레드에서 오랫동안 실행될 수 있지만 호출 스레드를 차단하지 않는 메서드 호출을 기반으로 합니다. 호출 스레드가 작업자 스레드가 실행중인 작업에 대한 정보를 획득해야하는 경우이를 수행하는 것은 호출 스레드에 달려 있습니다.

이벤트 기반 아키텍처는 실행되는 이벤트에 대한 응답으로 실행되는 코드 개념을 기반으로합니다. 일반적으로 코드 실행 타이밍은 결정적이지 않지만 이벤트는 차단 메서드를 호출 할 수 있습니다. 시스템이 이벤트 기반이라고해서 모든 것이 차단되지 않는다는 의미는 아닙니다.

일반적으로 비동기 아키텍처는 이벤트 기반 비 차단 아키텍처입니다.

비동기 호출이 이루어지면 호출자가 관심있는 일이 발생했음을 호출자에게 알리기 위해 동기화 서비스를 제공하는 API에 이벤트 핸들러가 등록됩니다. 그러면 호출이 즉시 반환되고 (비 차단 동작) 호출자는 자유롭게 실행을 계속할 수 있습니다. 이벤트가 호출 프로세스로 다시 시작되면 해당 프로세스의 일부 스레드에서 처리됩니다.

이벤트가 동일한 스레드에서 처리되는지 여부를 이해하는 것이 중요합니다. 이는 실행의 비 차단 특성에 영향을 미치기 때문입니다. 그러나 저는 개인적으로 단일 스레드에서 비동기 실행 관리를 수행하는 라이브러리를 알지 못합니다.

위의 단락은 명시된대로 엄격하게 정확하지 않기 때문에 삭제했습니다. 내 의도는 시스템 의 작업 이 OS 시설에 대한 호출 및 계속 실행과 같은 비 차단 적 임에도 불구하고 단일 스레드 실행의 특성상 이벤트가 발생하면 이벤트와 경쟁하게된다는 것을 의미합니다. 스레드의 계산 시간에 대한 기타 처리 작업.


마지막 단락이 "비동기 아키텍처는 ... 비 차단"이라는 귀하의 진술과 모순되지 않습니까?
nickb

나는 당신의 질문의 "정의"부분을 잘 다루지 못했다고 생각합니다. 업데이트를 게시하겠습니다. 그러나 아니요, 단일 스레드 실행의 특성은 모든 작업 이 실행되는 동안 본질적으로 차단 되어 비 동시성을 더욱 유용하게 만듭니다.
arootbeer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.