프로세스는 프로세스에 의해 만들어진다. 컴퓨터가 부팅이 되면 운영체제가 메모리에 올라오는데 운영체제가 처음으로 수행하는 일 중에 하나는 최초의 프로세스를 생성하는 것이다. 이렇게 처음 만들어진 프로세스가 다른 프로세스를 만들고 그 프로세스가 또 다른 프로세스를 만드는 과정을 반복한다.
위와 같이 최초의 프로세스는 Init이다. 이 이름은 운영체제마다 다르고, init은 UNIX 운영체제 기준 이름이다. 여기서 여러 다른 프로세스들이 생성되면 위와 같은 그림처럼 트리 모양으로 나타낼 수 있다.여기서 프로세스를 생성한 쪽을 부모 프로세스, 만들어진 프로세스를 자식 프로세스라고 한다. 같은 부모를 갖는 자식 프로세스 끼리는 서로 Sibling(형제) 프로세스라고 한다.
프로세스는 각각 고유의 번호를 갖는데 이를 PID(Process Identifirer)라고 한다. PID는 일반적으로 정수형(integer)으로 표현한다. PPID는 부모의 PID를 말한다.
새로운 프로세스를 만드는 시스템 콜이 존재하는데, 이는 fork()
라 한다. 만들어진 프로세스에서 어떠한 파일을 실행하려면 exec()
시스템 콜을 사용한다.
프로세스를 종료하는 시스템 콜은 exit()
이다. 한 프로세스가 종료되면 해당 프로세스가 사용한 모든 자원(메모리, 파일, I/O 등)을 회수해야한다. 이러한 회수된 자원과 권한은 모두 운영체제로 되돌아가야한다.
쓰레드는 프로그램 내부의 흐름(맥)이다.
int main(void)
{
int n = 0;
int m = 10;
while(n < m) {
n++;
}
return 0;
}
위와 같은 코드는 하나의 흐름을 가지고 있고 이를 쓰레드라고 부른다. 일반적으로 하나의 프로그램은 하나의 쓰레드를 갖는다.
스레드들은 하단의 그림처럼 프로세스의 code, data 영역이나 자원(file, I/O)들은 서로 공유하면서도, PC, SP 레지스터나 stack 처럼 서로 독립되어야 하는 부분은 공유하지 않는다. (함수 파라미터나 return address 등이 stack에 들어간감)
하나의 프로그램에 쓰레드가 2개 이상 존재하는 것을 다중 쓰레드라고 한다. 이렇게 한 프로그램에 여러 개의 쓰레드 즉, 흐름이 있을 수 있는 이유는 쓰레드가 빠른 시간 간격으로 스위칭되기 때문이다. 이러한 동작으로 사용자는 여러 쓰레드가 동시에 실행되는 것처럼 보인다.
다중 스레드에선 아주 짧은 시간동안 번갈아가며 각 스레드가 조금씩 실행되기 때문에, 사용자가 보기엔 마치 여러 스레드가 동시(simultaneous)에 실행되는 것 같이 보인다. 하지만 실상은 어디까지나 concurrent하다.
다중 쓰레드를 사용하는 대표적인 예는 Web browser 이다. 화면을 출력하는 쓰레드와 데이터를 읽어오는 쓰레드가 기본적으로 따로 수행하고 있다. 그 외에도 Word processor, Media player 등 현재 대부분의 프로그램은 다중 쓰레드로 동작한다.
워드 프로세서도 다중 스레드 프로그램이다. 예를 들어, 사용자가 키보드로 입력을 하고 있는데 철자나 문법이 틀리면 빨간줄을 밑에 그어준다. 이는 키보드 입력 스레드와 문법 검사 스레드가 따로 존재하기 때문에 가능한 것이다.
이전의 CPU 스케줄링에서 하나의 프로세스가 수행하다가 다른 프로세스로 넘어간다고 하였는데, 이는 예전의 방식이다. 현재 운영체제에서는 대부분 다중 쓰레드를 지원하기 때문에 하나의 프로세스 안에서 여러 쓰레드를 수행하다가 다른 프로세스로 넘어가서 그 프로세스의 쓰레드를 수행한다. 그러므로 현대 운영체제의 context switching 단위는 프로세스가 아닌 쓰레드 단위이다.
public class Test {
public static void main(String[] args) {
MyThread th = new MyThread();
th.start();
for(int i=0; i<1000; i++) {
System.out.print("A");
}
}
}
class MyThread extends Thread {
public void run() {
for(int i=0; i<1000; i++) {
System.out.print("B");
}
}
}
한 프로세스에는 기본적으로 하나의 쓰레드가 존재한다. 프로세스는 code, data, 메모리 공간이 존재하는데, 이는 여러 쓰레드가 공유한다. 이외에도 프로세스의 자원인 file, I/O 등은 여러 쓰레드가 공유하지만, 각 쓰레드가 고유하게 가지고 있는 것은 PC(Program Counter), SP(Stack Pointer), registers, stack 등이 있다.