프로세스의 시작점 main 함수
main 함수는 모든 프로세스의 시작점이다. 보통 프로세스가 실행되면, 메인스레드에서 main 함수가 실행되며, main 함수의 실행이 끝나면 종료된다. 메인 스레드는 사용자 스레드 중 하나이며, 프로세스는 사용자 스레드가 모두 종료되면, 종료되는 특성을 가지기 때문에 메인스레드만을 사용해 실행되는 프로세스는 메인 스레드의 사용이 종료되는 지점(main 함수의 실행이 완료되는 시점)에 종료된다.
예를 들어 위와 같은 코드를 실행하면 다음과 같은 결과가 나온다.
main 함수 입니다.
Process finished with exit code 0
자 이제 그림2와 같은 코드를 실행해보자. 그림2에서는 Main Thread가 아닌 IO Thread에 코루틴을 실행 요청해 println 함수를 실행 하도록 만들었다.
이에 대한 결과는 어떻게 나올까?
<그림2>의 코드의 결과는 <그림3>과 같다. 이유는 Dispatchers.IO에 실행 요청된 코루틴이 실행돼 출력이 일어나기 전에 메인 스레드의 작업이 모두 완료돼 프로세스가 종료되기 때문이다. Coroutine의 Dispatchers.IO가 사용하는 스레드들은 사용자 스레드가 아닌, 데몬 스레드(우선 순위가 낮은 스레드)이기 때문에 작업이 남아있더라도, 프로세스가 종료된다. 프로세스가 종료되면 데몬 스레드에 작업이 남아 있더라도 데몬 스레드의 작업은 강제 종료된다. 따라서 Dispatchers.IO에 실행 요청된 코루틴도 실행되기 전에 종료된다.
main 함수를 suspend fun으로 바꾸고 IO 디스패처에 실행 요청된 코루틴의 작업 실행 기다리기
이 문제를 해결하기 위해서는 main함수를 suspend fun으로 바꾸고 코루틴이 실행 완료될 때까지 기다리도록 만들면 된다.
자 이제 버튼을 눌러 main함수를 실행해보자. <그림5>와 같이 출력된다. 100 밀리초 내에 IO 스레드에서의 작업이 완료되었기 때문에 IO Thread에서 수행된 작업이 제대로 실행되는 것을 볼 수 있다.
다만, 이렇게 suspend fun 내부에서 CoroutineScope을 만들고, 해당 CoroutineScope에서 새로운 코루틴을 실행하는 것은 코루틴의 구조화를 깨기 때문에 지양해야 한다. 더 좋은 방법은 <그림6>과 같이 suspend fun에서 coroutineScope을 만들기 위해 coroutineScope 함수를 사용하고 해당 CoroutineScope 안에서 launch를 사용해 코루틴을 실행하는 것이다. 이에 관해서는 구조화된 동시성 섹션에서 추가로 다룬다.