본문 바로가기
C#/Threading

비동기 vs 동기

by PlaneK 2021. 9. 8.

개요

  동기 비동기
동시성 여러 종류 음식을 하나씩 조리함. 여러 종류 음식을 동시에 조리함.
일치화 손님이 올때까지 기다리다 같이 먹음. 손님을 기다리지 않고 먹음.

 

동기 방식

각 함수의 실행과 완료 시점이 일치한다. 한 시점에 모든 작업이 동시에 이뤄진다.

 

비동기 방식: 싱글 스레딩(코루틴)

using System.Collections;

public class Program
{
    public static IEnumerator A()
    {
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: Start A");
        yield return null;
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: End A");
    }
    
    public static void B()
    {
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: Start B");
        Thread.Sleep(3000);
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: End B");
    }
    
    public static void Main()
    {
        A().MoveNext();
        B();
        A().MoveNext();
    }
    /* 출력 결과
     * Main: Start A
     * Main: Start B
     * Main: End B
     * Main: End A
     */
}

각 함수의 실행 시점과 완료 시점이 맞닿아있다.
그러나 함수 A만 놓고 봤을 때는 실행과 완료 시점이 일치하지 않는다.
이 점에서 비동기 방식이라 할 수 있다(그러나 순차적으로 처리된다).

cf. 관점을 넓혀서 함수 A, B, C를 하나의 프로시져로 볼때는 동기적이다.

 

비동기 방식: 멀티 스레딩

public class Program
{
    public static async void A()
    {
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: Start A");
        await Task.Delay(1000); // 나머지 구문의 처리는 스레드풀에 위임한다.
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: End A");
    }
    public static void B()
    {
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: Start B");
        Thread.Sleep(3000);
        Console.WriteLine($"{((Thread.CurrentThread.ManagedThreadId == 1) ? "Main" : "Worker")}: End B");
    }
    
    public static void Main()
    {
        A();
        B();
    }
    /* 출력결과
    * Main: Start A
    * Main: Start B
    * Worker: End A
    * Main: End B
    */
}

위 코드에서는 A의 일부 코드 처리를 await 키워드를 사용해 스레드풀에 위임하고 동기화한다.
따라서 스레드풀을 관리하는 커널 모드가 나머지 코드의 실행 시점을 결정하고
작업자 쓰레드는 해당 코드를 처리하고 스스로 완료한다.
이는 사용자가 A의 실행 시점과 완료 시점을 정확히 알수 없다
멀티 스레딩 모델의 비동기 방식은 함수의 실행과 완료 시점이 일치하지 않고 병렬로 처리된다.

 

참고

디지털 논리회로 latch vs flip-flop
MSDN - 비동기 프로그래밍
위키백과 - Flip-Flop
위키백과 - 동기화
OKKY- 비동기 vs 동기 / 블록 vs 논블록

'C# > Threading' 카테고리의 다른 글

async/await 비동기 작업  (3) 2021.08.04

댓글