비동기 호출과 비 차단 호출의 차이점은 무엇입니까? 또한 차단과 동기 호출 사이에 (예제를 사용하십시오)?
답변
많은 상황에서 그것들은 같은 것에 대해 다른 이름이지만, 어떤 상황에서는 상당히 다릅니다. 따라서 다릅니다. 용어는 전체 소프트웨어 산업에서 완전히 일관된 방식으로 적용되지 않습니다.
예를 들어 기존 소켓 API에서 비 차단 소켓은 특별한 “차단할 것”오류 메시지와 함께 즉시 반환되는 반면, 차단 소켓은 차단 된 소켓입니다. 재 시도하기에 적합한시기 select
또는 poll
찾기 와 같은 별도의 기능을 사용해야합니다 .
그러나 비동기 소켓 (Windows 소켓에서 지원) 또는 .NET에서 사용되는 비동기 IO 패턴이 더 편리합니다. 메소드를 호출하여 조작을 시작하면 프레임 워크가 완료되면 다시 호출합니다. 여기에도 기본적인 차이점이 있습니다. 비동기 Win32 소켓은 Window 메시지를 전달하여 결과를 특정 GUI 스레드에 “마샬링”하는 반면 .NET 비동기 IO는 자유 스레드 (콜백을 호출 할 스레드를 모릅니다).
따라서 항상 같은 의미는 아닙니다. 소켓 예제를 공개하기 위해 다음과 같이 말할 수 있습니다.
- 블로킹과 동기는 같은 것을 의미합니다. API를 호출하면 응답이있을 때까지 스레드를 중단하고 반환합니다.
- 비 차단은 응답을 빠르게 반환 할 수없는 경우 API가 즉시 오류를 반환하고 다른 작업은 수행하지 않음을 의미합니다. 따라서 API를 호출 할 준비가되었는지 (즉, 효율적인 방식으로 대기를 시뮬레이션하고, 타이트한 루프에서 수동 폴링을 피하기 위해) 쿼리 할 수있는 관련 방법이 있어야합니다.
- 비동기는 요청을 이행하기위한 “백그라운드”노력을 시작한 API가 항상 즉시 리턴 함을 의미하므로 결과를 얻을 수있는 관련 방법이 있어야합니다.
답변
동기식 / 비동기식은 두 모듈 간의 관계를 설명하는 것입니다.
차단 / 비 차단은 하나의 모듈의 상황을 설명하는 것입니다.
예 :
모듈 X : “I”.
모듈 Y : “서점”.
X는 Y에게 묻습니다. “c ++ primer”라는 책이 있습니까?
1) 차단 : Y가 X에 응답하기 전에 X는 응답을 기다립니다. 이제 X (하나의 모듈)가 차단되고 있습니다. X와 Y는 두 개의 스레드 또는 두 개의 프로세스 또는 하나의 스레드 또는 하나의 프로세스입니까? 우리는 모른다.
2) 비 차단 : Y가 X에 응답하기 전에 X는 그냥 떠나서 다른 일을합니다. Y가 작업을 완료했는지 확인하기 위해 2 분마다 X가 다시 나타날 수 있습니까? 아니면 Y가 전화 할 때까지 X가 돌아 오지 않습니까? 우리는 모른다. 우리는 Y가 일을 끝내기 전에 X가 다른 일을 할 수 있다는 것을 알고 있습니다. 여기서 X (하나의 모듈)는 비 차단입니다. X와 Y는 두 개의 스레드 또는 두 개의 프로세스 또는 하나의 프로세스입니까? 우리는 모른다. 그러나 우리는 X와 Y가 하나의 스레드가 될 수 없다고 확신합니다.
3) 동기식 : Y가 X에 응답하기 전에 X는 응답을 계속 기다립니다. 이는 Y가 작업을 마칠 때까지 X를 계속할 수 없음을 의미합니다. 이제 우리는 말합니다 : X와 Y (두 모듈)는 동 기적입니다. X와 Y는 두 개의 스레드 또는 두 개의 프로세스 또는 하나의 스레드 또는 하나의 프로세스입니까? 우리는 모른다.
4) 비동기 : Y가 X에 응답하기 전에 X가 떠나고 X는 다른 작업을 수행 할 수 있습니다. Y가 전화 할 때까지 X는 돌아 오지 않습니다. 이제 우리는 말합니다 : X와 Y (두 모듈)는 비동기입니다. X와 Y는 두 개의 스레드 또는 두 개의 프로세스 또는 하나의 프로세스입니까? 우리는 모른다. 그러나 우리는 X와 Y가 하나의 스레드가 될 수 없다고 확신합니다.
위의 두 가지 굵은 문장에주의하십시오. 2)의 굵은 문장은 왜 2 개의 사례를 포함하고 4)의 굵은 문장은 하나의 사례 만 포함합니까? 이것이 비 차단과 비동기의 차이점의 핵심입니다.
비 차단 및 동기에 대한 일반적인 예는 다음과 같습니다.
// thread X
while (true)
{
msg = recv(Y, NON_BLOCKING_FLAG);
if (msg is not empty)
{
break;
}
sleep(2000); // 2 sec
}
// thread Y
// prepare the book for X
send(X, book);
이 디자인은 비 블로킹임을 알 수 있습니다 (대부분이 루프는 말도 안되는 일을하지만 CPU의 눈에는 X가 실행 중이므로 X는 비 블로킹을 의미합니다) .X는 X가 Y에서 책을 얻을 때까지 다른 일을 계속하지 마십시오 (X는 루프에서 뛰어 넘을 수 없습니다).
이 경우 일반적으로 비 차단은 바보 같은 루프에 많은 리소스를 소비하기 때문에 X 차단이 훨씬 좋습니다. 그러나이 예는 사실을 이해하는 데 도움이됩니다. 비 차단은 비동기를 의미하지 않습니다.
네 단어는 우리를 쉽게 혼란스럽게 만듭니다. 우리가 기억해야 할 것은 네 단어가 건축 설계에 도움이된다는 것입니다. 좋은 아키텍처를 디자인하는 방법을 배우는 것이이를 구별하는 유일한 방법입니다.
예를 들어, 우리는 그런 종류의 아키텍처를 설계 할 수 있습니다 :
// Module X = Module X1 + Module X2
// Module X1
while (true)
{
msg = recv(many_other_modules, NON_BLOCKING_FLAG);
if (msg is not null)
{
if (msg == "done")
{
break;
}
// create a thread to process msg
}
sleep(2000); // 2 sec
}
// Module X2
broadcast("I got the book from Y");
// Module Y
// prepare the book for X
send(X, book);
여기 예제에서 우리는 말할 수 있습니다
- X1은 비 차단
- X1과 X2는 동기식입니다
- X와 Y는 비동기입니다
필요한 경우 X1에서 작성된 스레드를 네 단어로 설명 할 수도 있습니다.
더 중요한 것은 : 비동기 대신 동기를 언제 사용합니까? 비 차단 대신 언제 차단을 사용합니까?
Nginx가 왜 차단되지 않습니까? Apache가 왜 차단됩니까?
올바른 선택을하려면 요구 사항을 분석하고 다양한 아키텍처의 성능을 테스트해야합니다. 다양한 요구에 적합한 아키텍처는 없습니다.
답변
- 비동기 는 병렬로 수행 된 것을 말합니다 . 즉 다른 스레드입니다.
- 비 차단 (non-blocking)은 종종 폴링 (polling )을 말합니다 . 즉, 주어진 조건이 유지되는지 확인합니다 (소켓을 읽을 수 있고 장치에 더 많은 데이터가있는 등).
답변
자바 7에서 NIO와 NIO.2의 맥락 에서이 질문을하면 비동기 IO는 비 블로킹보다 한 단계 앞선 것입니다. Java NIO 비 차단 호출의 경우을 호출하여 모든 채널 (SocketChannel, ServerSocketChannel, FileChannel 등)을 설정합니다 AbstractSelectableChannel.configureBlocking(false)
. 그러나 이러한 IO 호출이 반환 된 후에도 언제 다시 읽고 쓰는지 등의 검사를 제어해야 할 수 있습니다.
예를 들어,
while (!isDataEnough()) {
socketchannel.read(inputBuffer);
// do something else and then read again
}
Java 7의 비동기 API를 사용하면 이러한 컨트롤을보다 다양한 방법으로 만들 수 있습니다. 두 가지 방법 중 하나를 사용하는 것 CompletionHandler
입니다. 두 read
통화는 모두 차단되지 않습니다.
asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */,
new CompletionHandler<Integer, Object>() {
public void completed(Integer result, Object attachment) {...}
public void failed(Throwable e, Object attachment) {...}
}
}
답변
당신이 아마 다른 (그리고 종종 상호 배타적 인) 수많은 답변에서 볼 수 있듯이, 그것은 당신이 묻는 사람에 달려 있습니다. 어떤 분야에서는 용어가 동의어입니다. 또는 두 가지 유사한 개념을 각각 참조 할 수 있습니다.
- 한 가지 해석은 프로그램이 제어 할 필요가없는 긴 프로세스에 의해 프로그램이 유지되지 않도록하기 위해 본질적으로 감독되지 않은 백그라운드에서 호출이 무언가를 수행한다는 것입니다. 오디오 재생은 하나의 예일 수 있습니다. 프로그램은 mp3를 재생하는 기능 (예 : mp3)을 호출 할 수 있으며, 그 시점부터는 사운드 하드웨어에서 오디오를 렌더링하는 프로세스를 관리하기 위해 OS에 그대로두고 다른 작업을 계속할 수 있습니다. .
- 대체 해석은 호출이 프로그램이 모니터링해야하는 작업을 수행하지만 프로세스의 중요 시점에서만 프로그램에 알리는 백그라운드에서 대부분의 프로세스가 발생하도록 허용합니다. 예를 들어, 비동기 파일 IO는 예일 수 있습니다. 프로그램은 파일에 쓰기 위해 버퍼를 운영 체제에 제공하며, 작업이 완료되거나 오류가 발생하는 경우에만 OS가 프로그램에 알립니다.
두 경우 모두, 느린 프로세스가 완료되기를 기다리는 동안 프로그램이 차단되지 않도록하는 것입니다. 프로그램의 응답 방식이 유일한 차이입니다. 어떤 용어는 프로그래머에서 프로그래머로, 언어에서 언어로, 또는 플랫폼에서 플랫폼으로 변경되는 것을 말합니다. 또는이 용어는 완전히 다른 개념 (예 : 스레드 프로그래밍과 관련하여 동기식 / 비동기식 사용)을 나타낼 수 있습니다.
미안하지만 전 세계적으로 맞는 단일 답변이 있다고 생각하지 않습니다.
답변
블로킹 즉시 어떤 데이터 호출이 반환을 사용할 수 있습니다 바이트의 전체 수는 적은 요청하지 않거나 전혀 없음.
비동기 호출은 전체 (전체)에서 수행되지만 미래의 어느 시간에 완료 전송을 요청합니다.
답변
비 차단 :이 기능은 스택에있는 동안 기다리지 않습니다.
비동기 : 호출이 스택을 떠난 후 함수 호출 대신 작업이 계속 될 수 있습니다.