반응형

프로세스는 실행 중인 프로그램 ( 특정 매체에 저장된 오브젝트 코드) 입니다.

또한 프로세스는 사용중인 파일, 대기 중인 스그널, 커널 내부 데이터, 프로세서 상태, 하나 이상의 물리적 메모리 영역이 할 당 된 메모리 주소공간, 실행 중인 하나 이상의 스레드 정보등 ... 모든 자원을 포함 하는 개념입니다.

다시말해... 프로세스는 프로그램 코드를 실행하면서 생기는 무든 결과물이라고 할 수 있습니다.

 

스레드는 프로세스 내부에서 동작하는 객체입니다. 스레드는 프로그램 카운터와 프로세스 스택, 프로세스 레지스터를 갖고 있으며 커널은 프로세스가 아니라 각각의 스레드를 스케줄링합니다. 전통적인 유닉스 시스템에서는 프로세스가 하나의 스레드로 구성되지만 현대 시스템에서는 여러개의 스레드로 구성된 다중 스레드 프로그램을 볼수 있습니다. 또한 리눅스는 프로세스와 스레드를 구분하지 않으며 리눅스에 있어서는 스레드는 조금 특별한 형태의 프로세스입니다.

 

운영체제에서 프로세스는 가상 프로세서와 가상 메모리 라는 두가지의 가상환경을 제공합니다.

 

가상 프로세스는 실제로는 수백개의 프로세스가 프로세서(CPU)를 공유하는 상황일지라도 프로세스가 혼자 시스템을 사용하는 듯한 가상환경을 제공해줍니다.

가상 메모리는 프로세스가 시스템의 전체메모리를 혼자 차지하고 있는 것 처럼 메모리를 할당하고 관리할 수 있게 해준다.

 

스레드는 가상 프로세서를 할당 받지만, 가상 메모리는 공유합니다.

 

 

커널은  프로세스 목록을 테스크 리스트라고 부르는 환형 양방향 연결 리스트 형태로 저장한다. 각 항목은 <linux/sched.h>에 정의된 struct task_struct 형식으로 저장되어 있으며 프로세스 서술자라고 부르고 프로세스 서술자는 해당 프로세스와 관련된 모든 정보를 포함하고 있다.

 

 

task_struct 구조체는 객체 재용 및 캐시 컬러링 기능을 지원하는 슬랩 할당자(Slab Allocator)를 사용해 할당한다. 슬랩 할당자를 이용해 동적으로 프로세스 서술자를 만들기 때문에 thread_info라는 새로운 구조체를 스택 밑바닥이나 꼭대기에 두고 있다.

x86 시스템의 thread_info 구조체는 <asm/thread_info.h>에 다음과 같이 정의됩니다. 각 태스크의 thread_info 구조체는 프로세스 스택의 제일 끝부분에 할당이 되며 구조체의 task 포인터가 태스크의 실제 task_struct 구조체를 가르킵니다.

 

 

시스템은 고유한 프로세스 인식번호(PID)를 이용해 프로세스를 구별한다. PID는 보통 int형을 사용하고 PID의 최대 값은 32,768이며 4백만으로 상향 조정가능합니다.

 

프로세스 서술자의 state 항목은 현재 프로세스의 환경을 알려주고 시스템의 프로세스는 다섯가지 상태중에 하나에 있으며 각 상태값은 다음 다섯가지 플래그를 통해 표현 된다

 

1. TASK_RUNNING

프로세스가 실행 가능한 상태, 현재 실행 중이거나 실행되기 위해 실행되기 위해 실행 대기열에 있는 상태. 사용자 공간에서 실행된 프로세스는 이 상태만 가질수 있으며 커널 공간에서 실행 중인 프로세스도 이 상태에 속합니다.

2. TASK_INTERRUPTIBLE

프로세스가 특정 조건이 발생하기를 기다리며 쉬는 중이다(중단된 상태) 기다리는 조건이 발생하기를 기다리며 쉬는 중이고 기다리는 조건이 발생하면 커널의 프로세스의 상태를 TASK_RUNNING 상태로 바꾼다 프로세스가 시그널을 받은 경우 조건에 상관없이 실행 가능한 상태로 바꿉니다.

3. TASK_UNINTERRUPTIBLE

시그널을 받아도 실행가능상태로 바뀌지 않는 점을 빼면 TASK_INTERRUPTIBLE 상태와 같다. 이 상태는 기 다리는 조건이 금방 발생하는 경우에 사용되며 자주 사용되지는 않습니다.

4. __TASK_TRACED

디버거 등의 다른 프로세스가 ptrace를 통해 해당 프로세스를 추적하는 상태이다.

5. __TASK_STOPPED

프로세스 실행이 정지된 상태다 해당 테스크는 실행 중이지도 않고 실행가능한 상태도 아니다. 작업이 SIGSTOP, SGTSTP, SIGTTIN, SIGTTOU같은 시그널을 받은 경우 디버그 중에 시그널을 받은 경우에도 이상태가 된다.

 

 

 

커널 코드에서 프로세스의 상태를 바꿀 필요가 생기는 경우가 많이 발생한다. 이경우에는 다음의 함수를 사용하게 됩니다.

 

set_task_state(task, state); // 태스크 'task'의 상태를 'state' 상태로 설정

 

이 함수는 특정 태스크의 상태를 지정한 상태로 변경하며 필요한 경우, 메모리 보호 기능을 이용해 다른 프로세서와 작업 순서가 겹치는 것을 방해 한다.

 

이 함수의 동작은 아래와 같다.

task->state=state;

 

프로세스의 중요한 부분 중 하나는 실행 중인 프로그램 코드다. 프로그램이  시스템 호출을 하거나 예외 처리가 발생한 경우 프로그램은 커널 공간으로 진입하게되고 이런 상황을 커널은 '프로세스를 대신해 실행 중' 이거나 '커널이 프로세스 컨텍스트에 있다'라고 말한다. 커널이 작업을 끝내면 프로세스는 사용자 공간에서 실행르 계속한다.

 

시스템호출과 예외 처리기는 잘 정의된 커널 진입 인터페이스이며 프로 세스는 이 두가지 인터페이시를 통해 커널 공간으로 들어갈 수 있다.

 

 

반응형

+ Recent posts