Image
Coroutines/Coroutine Basics

[Coroutine 부록] 1. main 함수 suspend fun으로 만들기

프로세스의 시작점 main 함수

 main 함수는 모든 프로세스의 시작점이다. 보통 프로세스가 실행되면, 메인스레드에서 main 함수가 실행되며, main 함수의 실행이 끝나면 종료된다. 메인 스레드는 사용자 스레드 중 하나이며, 프로세스는 사용자 스레드가 모두 종료되면, 종료되는 특성을 가지기 때문에 메인스레드만을 사용해 실행되는 프로세스는 메인 스레드의 사용이 종료되는 지점(main 함수의 실행이 완료되는 시점)에 종료된다.

 

 예를 들어 위와 같은 코드를 실행하면 다음과 같은 결과가 나온다.

main 함수 입니다.

Process finished with exit code 0

 

 자 이제 그림2와 같은 코드를 실행해보자. 그림2에서는 Main Thread가 아닌 IO Thread에 코루틴을 실행 요청해 println 함수를 실행 하도록 만들었다.

그림2. main 함수 내에서 새로운 CoroutineScope에서 실행되는 코루틴

 

 이에 대한 결과는 어떻게 나올까?

그림3. 실행 결과

 

<그림2>의 코드의 결과는 <그림3>과 같다. 이유는 Dispatchers.IO에 실행 요청된 코루틴이 실행돼 출력이 일어나기 전에 메인 스레드의 작업이 모두 완료돼 프로세스가 종료되기 때문이다. Coroutine의 Dispatchers.IO가 사용하는 스레드들은 사용자 스레드가 아닌, 데몬 스레드(우선 순위가 낮은 스레드)이기 때문에 작업이 남아있더라도, 프로세스가 종료된다. 프로세스가 종료되면 데몬 스레드에 작업이 남아 있더라도 데몬 스레드의 작업은 강제 종료된다. 따라서  Dispatchers.IO에 실행 요청된 코루틴도 실행되기 전에 종료된다.

 

main 함수를 suspend fun으로 바꾸고 IO 디스패처에 실행 요청된 코루틴의 작업 실행 기다리기

이 문제를 해결하기 위해서는 main함수를 suspend fun으로 바꾸고 코루틴이 실행 완료될 때까지 기다리도록 만들면 된다.

그림4. main 함수 suspend fun으로 바꾼 후 코루틴 실행 완료 기다리기

 

 

 자 이제 버튼을 눌러 main함수를 실행해보자. <그림5>와 같이 출력된다. 100 밀리초 내에 IO 스레드에서의 작업이 완료되었기 때문에 IO Thread에서 수행된 작업이 제대로 실행되는 것을 볼 수 있다.

그림5. 결과

 

다만, 이렇게 suspend fun 내부에서 CoroutineScope을 만들고, 해당 CoroutineScope에서 새로운 코루틴을 실행하는 것은 코루틴의 구조화를 깨기 때문에 지양해야 한다. 더 좋은 방법은 <그림6>과 같이 suspend fun에서 coroutineScope을 만들기 위해 coroutineScope 함수를 사용하고 해당 CoroutineScope 안에서 launch를 사용해 코루틴을 실행하는 것이다. 이에 관해서는 구조화된 동시성 섹션에서 추가로 다룬다.

그림6. suspend fun 안전하게 사용하기

반응형

 

이 글의 저작권은 '조세영의 Kotlin World' 에 있습니다. 글, 이미지 무단 재배포 및 변경을 금지합니다.

 

 

Kotlin, Android, Spring 사용자 오픈 카톡

오셔서 궁금한 점을 질문해보세요!
비밀번호 : kotlin22

open.kakao.com