[c#] async는 멀티 뜨레드가 아니다
synchronous는 ‘순서대로 처리한다’는 뜻이다. 반대말은 앞에 부정 접두사 a가 붙어서 asynchronous다. ‘동시에 처리한다’는 의미다. 멀티 뜨레드를 이용하면 동시 처리를 할 수 있으니 멀티 뜨레드는 asynchornous하다. 그러나 async가 곧 멀티 뜨레드를 이용한다는 건 아니다. async가 멀티 뜨레드와 같은 거라면 굳이 따로 있을 리가 없다.
async는 작업을 매인 뜨레드에서 처리하면서 마치 멀티 뜨레드를 이용하는 것처럼 보이게 하는 수식어다. 아래의 코드에서 Method1은 마치 동시에 작동하는 거처럼 보인다.
private void button1_Click(object sender, EventArgs e)
{
Method1(true);
}
private void button2_Click(object sender, EventArgs e)
{
Method1(false);
}
async void Method1(bool bool1)
{
if (bool1)
{
await Task.Delay(5000);
}
textBox1.AppendText(bool1.ToString() + "\r\n");
}
버튼 1을 클릭하면 5초를 기다리는 Method1이 실행된다. 이게 기다리는 동안 버튼 2를 누르면 또 다른 Method1이 작동하며 바로 false를 출력한다. 그러나 이들은 모두 매인 뜨레드에서 작동한다. 단지 스케줄링이 된 거 뿐이다.
An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete. … If the method that the async keyword modifies doesn’t contain an await expression or statement, the method executes synchronously.
async를 쓴다 하여 그 메떠드가 통째로 비동기로 작동하는 건 아니라는 말이다. 기본적으로 여느 메떠드처럼 동기로 작동하지만 단지 await를 만난 때에만 마치 새로운 뜨레드에서 작동하는 거처럼 동시에 작업을 한다.
async는 cpu를 효율적으로 쓰기 위한 게 아니다. 단지 물리적으로 무언가를 기다려야 할 때 매인 뜨레드가 먹통이 되지 않게 하기 위해 쓴다. 동시 연산을 위해 써 봐야 cpu는 하나의 코어나 논리 프로세스의 한계를 넘어서지 못한다. 예를 들어 6개의 코어들이 있고 12개의 논리 프로세서들이 있는 cpu라면 async를 쓴다 한들 어차피 논리 프로세서 하나에 갇혀 최대 1/12인 8.3% 정도밖에 cpu를 쓰지 못한다. 더 많이 쓰려면 멀티 뜨레드로 구현해야 한다.