스레드(thread)는 어떠한 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 일반적으로 한 프로그램은 하나의 스레드를 가지고 있지만, 프로그램 환경에 따라 둘 이상의 스레드를 동시에 실행할 수 있다. 이러한 실행 방식을 멀티스레드(multithread)라고 한다.
멀티프로세스와 멀티스레드는 양쪽 모두 여러 흐름이 동시에 진행된다는 공통점을 가지고 있다. 하지만 멀티프로세스에서 각 프로세스는 독립적으로 실행되며 각각 별개의 메모리를 차지하고 있는 것과 달리 멀티스레드는 프로세스 내의 메모리를 공유해 사용할 수 있다. 또한 프로세스 간의 전환 속도보다 스레드 간의 전환 속도가 빠르다.
멀티스레드의 다른 장점은 CPU가 여러 개일 경우에 각각의 CPU가 스레드 하나씩을 담당하는 방법으로 속도를 높일 수 있다는 것이다. 이러한 시스템에서는 여러 스레드가 실제 시간상으로 동시에 수행될 수 있기 때문이다.
멀티스레드의 단점에는 각각의 스레드 중 어떤 것이 먼저 실행될지 그 순서를 알 수 없다는 것이 있다. 예를 들어, 두 스레드가 특정 공유 변수 i의 값을 1 증가시키는 명령을 실행할 때, 다음과 같은 방식으로 수행될 수 있다.
1. 공유되는 변수 i의 값을 레지스터에 저장한다.
2. 레지스터의 값을 1 증가시킨다.
3. 변수 i에 그 값을 저장한다.
멀티스레드 환경이 확산됨에 따라 전통적인 프로세스 관리 방식에도 변화가 필요해졌다. 예를 들어, fork 또는 exec와 같은 시스템 호출시에 어떻게 처리할 것인가 하는 문제가 대두된 것이다.
fork 문제 : 어떤 프로세스 내의 스레드가 fork를 호출하면 모든 스레드를 가진 프로세스를 생성할 것인지, 아니면 fork를 요청한 스레드만 가진 프로세스를 생성할 것인지 하는 문제이다. 유닉스에서는 각각 2가지 버전의 fork를 지원하고 있다.
exec 문제 : fork를 통해 모든 스레드를 복제하고 난 후, exec를 수행한다면 모든 스레드들이 초기화된다. 그렇다면 교체될 스레드를 복제하는 작업은 필요가 없기 때문에 애초에 fork를 요청한 스레드만을 복제했어야 한다. 한편, fork를 한 후에 exec를 수행하지 않는다면 모든 스레드를 복제할 필요가 있는 경우도 있다.
프로세스(process)는 컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램이다. 종종 스케줄링의 대상이 되는 작업(task)이라는 용어와 거의 같은 의미로 쓰인다. 여러 개의 프로세서를 사용하는 것을 멀티프로세싱이라고 하며 같은 시간에 여러 개의 프로그램을 띄우는 시분할 방식을 멀티태스킹이라고 한다.
프로그램과 프로세스는 구별없이 혼용되기도 한다. 다만, 프로그램은 하드디스크 등에 저장되어 있는 실행코드의 성격이 강한 반면, 프로세스는 프로그램을 구동하여 메모리에 적재된 상태로 실행되는 하나의 작업 단위이다. 예를 들어, 하나의 프로그램을 여러 번 구동하면 여러 개의 프로세스로 메모리에 적재되어 실행되는 것이다.
프로세스의 상태
커널 내에는 준비 큐, 대기 큐, 실행 큐 등의 자료구조가 있으며 커널은 이것들을 이용하여 프로세스의 상태를 관리한다.
* 생성(new) : 프로세스가 생성되는 중이다.
* 실행(running) : 프로세스가 CPU를 차지하여 명령어들이 실행되고 있다.
* 준비(ready) : 프로세스가 CPU를 사용하고 있지는 않지만 언제든지 사용할 수 있는 상태로, CPU가 할당되기를 기다리고 있다. 일반적으로 준비 상태의 프로세스 중 우선순위가 높은 프로세스가 CPU를 할당받는다.
* 대기(waiting) : 보류(block)라고 부르기도 한다. 프로세스가 입출력 완료, 시그널 수신 등 어떤 사건을 기다리고 있는 상태를 말한다.
* 종료(terminated) : 프로세스의 실행이 종료되었다.
프로세스의 상태전이
하나의 작업이 시스템에 입력되면 거기에 대응되는 프로세스가 생성되어 준비 리스트의 끝에 들어간다. 시간이 지남에 따라 그 프로세스는 점차 준비 리스트의 앞으로 나가게 되고 언젠가 CPU를 사용할 수 있게 된다.
* 디스패치(dispatch)
준비리스트의 가장 앞에 있던 프로세스가 CPU를 점유하게 되는 것, 즉 준비 상태에서 실행 상태로 바뀌는 것을 디스패치라고 하며 다음과 같이 표시한다.
dispatch (processname) : ready → running
* 보류(block)
실행 상태의 프로세스가 허가된 시간을 다 쓰기 전에 입출력 동작을 필요로 하는 경우 프로세스는 CPU를 스스로 반납하고 보류 상태로 넘어 간다. 이것을 보류라고 하며 다음과 같이 표시한다.
block (processname) : running → blocked
* 깨움(wakeup)
입출력 작업 종료 등 기다리던 사건이 일어났을 때 보류 상태에서 대기 상태로 넘어가는 과정을 깨움이라고 하며 다음과 같이 표시한다.
wakeup (processname) : blocked → ready
스레드와 프로세스
"스레드"와 "프로세스"는 컴퓨터 분야에서 서로 연관된 개념입니다. 이 둘은 모두 특정 순서로 실행해야 할 명령 시퀀스를 나타냅니다. 그러나 개별 스레드 또는 프로세스의 명령은 함께 실행할 수 있습니다.
프 로세스는 운영 체제 내에 있으며 사용자에게 프로그램이나 응용 프로그램으로 표시되는 항목에 해당합니다. 반면에 스레드는 프로세스 내에 있습니다. 따라서 스레드를 "간단한 프로세스"라고도 합니다. 각 프로세스는 하나 이상의 스레드로 구성됩니다.
여 러 개의 프로세스가 있으면 컴퓨터에서 한 번에 여러 작업을 수행할 수 있습니다. 여러 개의 스레드가 있으면 프로세스를 분할하여 작업을 병렬로 수행할 수 있습니다. 다중 프로세서 시스템에서는 프로세스나 스레드를 서로 다른 프로세스에서 실행하여 진정한 의미에서 병렬 처리를 수행할 수 있습니다.
완벽한 병렬 처리가 항상 가능한 것은 아닙니다. 때로는 스레드를 동기화해야 합니다. 한 스레드에서 다른 스레드의 결과를 기다려야 하거나 다른 스레드에서 사용하고 있는 리소스를 한 스레드에서 독점적으로 액세스하여 사용해야 할 수도 있습니다. 동기화 문제는 다중 스레드 응용 프로그램에서 버그를 발생시키는 주요 원인입니다. 때로는 스레드에서 사용 가능하지 않은 리소스를 기다리게 되어 "교착 상태"가 발생할 수 있습니다.
'백엔드기술 > 개발언어' 카테고리의 다른 글
뮤텍스 (Mutex) (0) | 2009.12.09 |
---|---|
Shuffle Array (0) | 2009.12.09 |
Swing Demo (0) | 2009.12.09 |