App노자

[Kotlin] 프로세스와 스레드 본문

Android/Kotlin

[Kotlin] 프로세스와 스레드

앱의노예 2023. 8. 20. 20:05

1. 동시성 프로그래밍


동시성 프로그래밍(Concurrency Programming)은 컴퓨터 프로그램에서 

여러 작업이 동시에 실행되는 상황을 다루는 프로그래밍 기법이다

여기서 "동시에 실행"은 물리적으로 동시에 실행되는 것이 아니라 매우 짧은 시간 동안 번갈아 가며 실행되는 것을 의미한다

프로그래밍에서 순서대로 작업을 수행하여 1개의 루틴을 완료한 후 다른 루틴을 실행하는 방식을 동기적이라고 한다

순차적인 프로그램보다 로딩되는 UI를 보여줄 때 네트워크는 다운로드해야 하고,

목록을 끌어올리면 지속적으로 UI를 갱신하며 아이템 목록을 업데이트하는 등의 여러 개의 루틴이

선행 작업의 순서나 완료 여부와 상관없이 실행되어야 하는 경우가 많은데 이때 사용 되는 방식을 비동기적이라고 한다

 

Kotlin에서는 coroutine을 기본으로 제공하고 있다

하나의 개별적인 작업을 루틴이라고 하는데 coroutine이란 여러 개의 루틴들이 협력한다는 의미이다

위의 다이어그램에 Process A를 수행하다 입출력 과정이 수행될 때 Process B가 수행되면 Process A의 작업은

더 이상 진행되지 않고 다른 작업이 마무리될 때까지 코드는 멈추게 된다, 이런 상황을 블로킹하고 있다고 말한다

Process A가 블로킹하는 동안 운영체제의 스케줄링 정책에 따라 우선순위에 따라

태스크를 실행하고 다른 태스크는 블로킹하는 식의 방식으로 프로그램이 흘러간다

같은 상황에서 넌블로킹 형태의 프로세스는 입출력 요청을 하더라도 운영체제에 의해 시그널을 Process A가 받아서 실행을 재개할 수 있다 이때 Process A는 다른 루틴을 수행하다가 내부적으로 입출력 완료 시그널을 받은 후

콜백 루틴 또는 이벤트를 통해 완료된 이후의 일을 처리할 수 있다 

Process A를 수행하는 도중에 또 다른 Process B가 생성될 때는 운영체제의 스케줄링 기법에 따라 결정된다

프로세서 코어 수에 따라 동시에 수행될 수도 있고 자주 교환을 하면서 수행을 진행할 수 있다

여러 개의 코어가 매우 짧은 시간 동안 번갈아가며 실행되는 것을 병행수행(Concurrent Execution)이라고 한다

2. 프로세스와 스레드란?


태스크는 큰 실행 단위인 프로세스나 좀 더 작은 실행 단위인 스레드를 말한다

하나의 프로그램이 실행되면 프로세스가 시작되는데 프로세스는 실행되는 메모리, 스택, 열린 파일 등을 모두 포함하기 때문에

프로세스 간 문맥 교환을 할 때 많은 비용이 드는 반면에 스레드는 레지스터와 스택만 독립적으로 가지고 있고

대부분의 문맥은 프로세스 안에서 공유하므로 프로세스 간 전환보다 빠르고 운영체제 입장에서 문맥 교환 비용이 낮다

여기서 문맥 교환(Context Switching)이란 하나의 프로세스나 스레드가 CPU를 사용하고 있는 상태에서

다른 프로세스나 스레드가 CPU를 사용하도록 하기 위해,

이전의 프로세스의 상태를 보관하고 새로운 프로세스의 상태를 적재하는 과정을 말한다

Kotlin의 coroutine은 문맥 교환이 없고 비동기 함수를 통해 비선점형으로 작동하는 특징이 있어 협력형 멀티태스킹을 구현할 수 있다

3. 스레드 사용 방법


// Thread클래스를 상속받아 구현하기
class SimpleThread: Thread() {
    override fun run() {
        println("Current Threads: ${Thread.currentThread()}")
    }
}

// Runnable 인터페이스로부터 run() 구현하기
class SimpleRunnable: Runnable {
    override fun run() {
        println("Current Threads(runnable): ${Thread.currentThread()}")
    }
}

fun main() {
    val thread = SimpleThread()
    thread.start()

    val runnable = SimpleRunnable()
    val thread1 = Thread(runnable)
    thread1.start()

    // 익명 객체를 이용한 스레드의 실행
    object : Thread() {
        override fun run() {
            println("Current Threads(object): ${Thread.currentThread()}")
        }
    }.start()

    // 람다식을 이용한 스레드의 생성
    Thread({
        println("Current Threads(lambda): ${Thread.currentThread()}")
    }).start()

    // 람다식을 이용한 스레드의 생성 (중괄호 생략 표현)
    Thread {
        println("Current Threads(lambda): ${Thread.currentThread()}")
    }.start()


}

스레드 루틴을 만들려면 Thread 클래스를 상속받거나 Runnable인터페이스를 구현한다

Thread 클래스로 상속받을 경우 다중 상속이 허용되지 않기 때문에 Thread 이외의 클래스를 상속할 수 없지만

Runnable 인터페이스로부터 구현한 경우 다른 클래스를 상속할 수 있다

스레드에서 실행할 코드는 run() 메서드를 오버라이딩해서 구현하고 해당 클래스 객체의 start() 메서드를 호출하면

각 스레드의 run() 본문을 수행하는 독립된 실행 루틴이 동작한다

public fun thread(start: Boolean = true, isDaemon: Boolean = false,
                  contextClassLoader: ClassLoader? = null, name: String? = null,
                  priority: Int = -1, block: () -> Unit): Thread {
    val thread = object : Thread() {
        public override fun run() {
            block()
        }
    }
    if (isDaemon)
        thread.isDaemon = true
    if (priority > 0)
        thread.priority = priority
    if (name != null)
        thread.name = name
    if (contextClassLoader != null)
        thread.contextClassLoader = contextClassLoader
    if (start)
        thread.start()
    return thread
}

fun main() {
    // 스레드의 옵션 변수를 손쉽게 설정할 수 있다.
    thread(start = true) {
        println("Current Threads(Custom function): ${Thread.currentThread()}")
        println("Priority: ${Thread.currentThread().priority}")
        println("Name: ${Thread.currentThread().name}")
        println("Name: ${Thread.currentThread().isDaemon}")
    }
}

start나 기타 매개변수로 상태 제어를 하기 위해 추가 람다식을 작성할 수 있다

스레드의 우선순위, 백그라운드 여부, 이름 등 스레드가 가져야 할 옵션, 변수를 설정할 수 있으며 옵션을 적지 않으면 기본값이 사용된다

JVM에서 priority(우선순위)는 10단계까지 있으며 기본값은 5가 할당된다

 

'Android > Kotlin' 카테고리의 다른 글

[Kotlin] Coroutines (launch, async)  (0) 2023.09.05
[Kotlin] object 키워드  (0) 2023.08.15
[Kotlin] Closure (클로저)  (0) 2023.08.10
[Kotlin] 코틀린 표준 라이브러리  (0) 2023.08.09
[Kotlin] by 키워드  (0) 2023.08.06