프로세스와 스레드
프로세스는 여러 컴퓨터 프로그램들을 동시에 실행할 수 있는 컴퓨터 시스템에 의해서 순서되로 실행된는 하나 또는 그이상의 스레드로 구성된 컴퓨터 프로그램의 인스턴스이다.
컴퓨터 프로그램은 수동적인 명령(어)들의 모음이지만, 프로세스는 이러한 명령(어)들의 실재 실행을 의미한다. 예들들어 같은 컴퓨터 프로그램의 여러 인스턴스들을 시작한다는 것은 하나 이상의 프로세스가 실행된다는 의미이다.
단일 컴퓨터 CPU는 (클럭 사이클 마다) 한번에 하나 또는 그 이상의 명력(어)들을 실행한다. (슈퍼스칼라 CPU 아키텍처 참조)
사용자가 여러 프로그램을 한꺼번에 실행하려면, 단일 CPU 시스템은 시분할(time-sharing) 을 할 수 있어야 한다. 시분할(time-sharing)은 프로세스들이 실행과 실행대기 사이를 전환(switch)할 수 있게 하는데, 대부분의 경우 전환은 아주 빠르게 이뤄지기 때문에, 여러 프로세스들이 동시에 실행되는 것과 같은 효과를 제공한다. 하나 이상의 CPU 을 사용한다면 보다 실제에 근접하는 동시 실행을 가능하게 할 것이다.
자바가상머신을 프로세스라고 한다면 스레드는 자바가상머신에 의하여 수행되는 바이코드 명령들의 순서라고 볼수 있다. 스레드에는 명령들의 순서, 메소드들의 의하여 사용되는 지역변수와 인자들(런타임 스택)이 저장된다. 스레드들은 자신만의 런타임 스텍을 갖고 있기 때문에 지역변수와 인자값들은 항상 스레드에 안전하게 된다. 즉 어떤 스레드에서 다른 스레드의 러타임 스텍에 접근할 수 있는 방법이 제공되지 않는 것이다. 이러한 이유에서 힙 메모리에 저장된는 정턱 필드와 객체의 모든 필드들에 대한 접근이 없는 메소드는 다른 스레드들로 부터서 안전하게 동작할 수 있다.
스레드에 안전하다는 것(thread-safe)은 메소드가 다중 스레드 환경에서 안전하게 동작할 수 있다는 것을 의미한다. 즉 스레드는 프로세스 수준 (자바가상머신의 스텍) 에서 공유되는 데이터를 여러 다른 스레드들과 함께 안전하고 효율적으로 접근할 수 있어야 할 것이다.
동기화
스레드 안정성의 핵심에는 동기화라는 개념이 있다. 동기화란, 여러개의 스레드가 동시에 안전하게 동작할 수 있게 하는 매커니즘을 의미한다. 자바는 다음 두가지 고유한 동기화 매커니즘을 가지고 있다.
- 동기화된(synchronized) 블럭과 함수
- 휘발성(volatile) 변수
전통적으로 시스템의 한정된 자원이 특정 프로세스에 점유되었는지 여부를 표시하기 위하여 세마포어(Semaphore)라는 용어를 많이 사용한다. C에서는 시스템의 모든 자원들은 세마포어라는 플래그가 존재하고 이 세마포어를 먼저 획득한 프로세스 만이 리소스를 점유하여 사용하는 개념으로 사용된다.
세마포어는 수기신호라는 의미이다. 즉, 어떤 자원의 상태를 수기신호에 비유해 운영체제 내부에서 사용가능, 또는 사용불가의 상태를 관리하는 정도로 이해하면 된다. 시스템 관점에서는 동시에 다수의 프로세스가 동일한 자원을 점유하여 시스템이 불안정해지는 것을 방지하기 위한 개념이라고 할 수 있다.
자바는 이 개념을 객체에 적용하여 뮤텍스(mutex:Mutual Exclusion)라는 용어로 부른다. 즉, 동시에 하나의 객체 인스턴스에 접근할 수 있는 스레드는 오직 하나만 존재하여야 한다는 개념이다.
다른 말로는 객체 락(Object lock) 라고 표현하기도 하는데 각 객체에 해당하는 락를 먼저 획득하는 스레드가 해당 객체을 사용할 수 있다는 개념이다. 당연이 락(lock)을 획득한 스레드가 락을 풀어주기 전에는 다른 스레드는 그 객체를 사용할 수 없게 된다.
동기화을 사용하면 어떤 스레드가 락을 획득하든지 스레드는 주어진 변수들에 대한 단독 접근과 변경을 할 수 있도록 보호받으며, 스레드들이 다음으로 락을 획득할때 변수들이 보여지게 된다.
동기화에 가장 문제시 되는 부분은 오버헤드이다. 만일 스레드들은 서로 락을 획득하기 위하여 지나치게 경쟁을 하게 되면, 아주 비효율적으로 동작하게 된다. 락을 이용한 동기화의 또다른 문제는 어떤 이유에서 락을 가지고 있는 스레드가 지연된다면, 어떤 스레드로 락을 획득하지 못하게 된다.
휘발성(volatile) 변수는 "synchronized" 의 가시성 기능을 제공한다. (원자성 기능을 제공하지 않는다.) 이는 스레드들은 자동적으로 가장 최근에 수정된 휘발성(volatile) 변수 값을 볼수 있음을 의미한다. 아주 제안된 경우에만 사용한다면 스레드에 안전한게 동작할 것이다.
- 자신의 현재 값에 의존하지 않는 변수에 사용.
- 다른 변수들과 함께 변하지 않는 값으로 사용되지 않는 경우.
댓글 없음:
댓글 쓰기