Tistory View

Android Develop

Android 쓰레드 우선순위 설정하기

God Dangchy What should I do? 2021. 8. 26. 18:03

Android는 Java를 이용하기 때문에(*1), Java의 우선순위설정을 사용하여 Thread의 우선순위(*3)를 정할 수 있다.

Java에서 현재 Thread의 우선순위설정하려면 다음과 같이 한다.

 

Thread.currentThread().setPriority( int priority );

 

이 코드에서 priority 값은 10~1값을 넣어주면된다.

보통 쓰레드가 생성되는 중간정도의 (중간값,기본값) 값은 5로 되어 있다.

 

Java 프로그래밍에 익숙한 독자라면, 이 코드는 그리 어렵지 않다.

 

하지만, 위의 코드로 아무리 최고값인 Thread.MAX_PRIORITY값을 넣어도 끊기는 경우가 있다. 특히 음악과 같이 소리를 실시간으로 처리하는 앱에서 주로 발생하게 된다(*2). Thread의 최고치를 주었는 데에도 이런 경우면 대체 뭐가 문제인지 궁금할 것이다.

 

Program scheduling priority

위에서 언급한 우선순위는 Java의 우선순위(Dalvik or ART)를 결정하는 것이다. Native Thread의 우선순위를 바꾸는 것은 또 따로 존재한다. 자바에서는 다음의 함수로 이 우선순위를 변경할 수 있다.

 

android.os.Process.setThreadPriority( int priority )

 

priority : -20[제일 높은 우선순위] ~ +19(제일 낮은 우선순위)

 

이 priority는 Google에서 권장하는 값을 이미 상수로 정해 놓았다. 그 값은 다음과 같다.

우선순위 설명
THREAD_PRIORITY_LOWEST 19 가장 낮은 우선 순위 : 진짜 아무것도 할 게 없을 때 실행된다.
THREAD_PRIORITY_BACKGROUND 10 사용자 인터페이스보다도 떨어지는 반응성
THREAD_PRIORITY_FOREGROUND -2 사용자 인터페이스용 정도의 쓰레드
THREAD_PRIORITY_DISPLAY -4 사용자의 인터페이스 반응정도의 화면이 그려져야 하는 정도
THREAD_PRIORITY_URGENT_DISPLAY -8 사용자의 반응에 즉각적으로 화면이 반응해야 하는 정도
THREAD_PRIORITY_VIDEO -10 비디오처리용
THREAD_PRIORITY_AUDIO -16 오디오처리용
THREAD_PRIORITY_URGENT_AUDIO -19 실시간오디오 처리용

기본적으로 어떠한 설정을 하지 않았다면, 이 priority값은 0으로 시작하고, Main Thread와 같이 반응성이 있는 쓰레드는 -2~0사이를 알아서 '왔다갔다' 하게 된다. 위에 써있는 값이 사실상 구글에서 제시하는 최적의 값이니, 이 값을 사용하면 거의 무리없이 잘 동작한다.

 

적당한 값을 고르는 것이 중요하다.

실제 priority값을 -20으로 설정할 경우, 오히려 전반적으로 기기가 이상하게 동작을 하는 것을 알 수 있다. 또한 background로 돌아갈 정도의 Thread를 높은 우선순위를 부여할 경우, 오히려 다른 Thread가 느려질 수 있다. 멀티코어를 사용하는 상황이라 이런 일이 발생하지 않을 것 같지만, process들은 core를 이리저리 이동하게 되고(*4), 다른 코어라도 대기중이던 쓰레드에서 어떤 것을 먼저 깨울지는 이 우선순위로 결정되기 때문에, 빠른놈이 계속 깨어나면서 다른 Thread에게 영향을 미치게 된다.

 

위의 표에서 DISPLAY보다 AUDIO가 더 높은 우선순위가 필요하다. 실제 데이터의 양은 DISPLAY용이 이미지를 다루기 때문에 오디오 데이터보다 더 많다. 하지만, 이미지는 순간에 많은 양 계산을 해야하지만, 오디오 데이터는 처리해야할 순간을 놓치면 바로 끊김이 발생하기 때문에 더 높은 우선순위가 필요하다.

 

 

Native에서 사용하려면..

Native에서 사용하려면 다음의 함수가 있다.

 

int setpriority( PRIO_PROCESS, 0, int prio);

 

이 함수가 android.os.Process.setThreadPriority()함수와 거의 같은 역할을 한다. prio는 위의 표와 같은 값이다.

하지만 이 함수와 android.os.Process.setThreadPriority()함수가 동일한 역할을 하지 않기 때문에, 필자는 JNI로 android.os.Process.setThreadPriority()함수를 호출해서 쓰기를 권장한다.

 

추가로..

Thread.currentThread().setPriority( Thread.MAX_PRIORITY )를 사용하여 지정하면, Program scheduling priority값이 [-8]이던가?로 변한다. 이 다음에 android.os.Process.setThreadPriority로 다른 값을 지정하면 Java Thread의 Thread.MAX_PRIORITY값은 계속 유지가 된다.

 

android.os.Process.setThreadPriority()함수만 사용하면 웬만하면 문제없지만, Java에서 정확히 Davik이나 ART에서 더 빠르게 처리하려면 두가지 모두를 조정해야 할 수도 있다.

 


*1 : Java를 이용하지 않고도 실행파일을 만들 수 있다. 하지만 대부분의 경우 Java를 이용하기 때문에, Java를 쓴다는 가정하여 작성한다.

*2 : 화면이 켜져있는 상황에서는 발생하지 않지만, 꺼져있는 경우에 발생한다면, 다음의 링크로 해결 할 수 있다.

https://developer.android.com/reference/android/os/PowerManager.WakeLock

 

PowerManager.WakeLock  |  Android Developers

 

developer.android.com

 

*3 : "빠르다/느리다"라는 표현보다 동시에 진행을 시켜야 하는 상황에서 어떤 것을 "먼저/오랜동안 실행"시킬지를 의미한다. 그런 의미에서 우선순위를 아주 적절할 표현이다.

*4 : 코어이동을 막거나 정하려면 다음의 글을 참조하라.

https://jamssoft.tistory.com/225

 

안드로이드 쓰레드를 CPU의 특정 코어로 이동하기

쓰레드를 생성 후 만들어진 쓰레드를 CPU의 특정 코어로 이동할 수 있다. 필자가 알기로는 쓰레드를 생성하면서 코어를 지정하는 방법은 없는 것으로 알고 있다. 따라서, 쓰레드를 만들고 만들어

jamssoft.tistory.com

 

Replies
Reply Write