티스토리 뷰
프로세스의 생성과 복사, 전환
- 프로그램이 실행할 때 프로세스를 새로 생성.
- fork() 시스템 호출을 통해 실행중인 부모 프로세스를 복사하여 똑같은 내용의 새로운 자식 프로세스 생성.
- exec() 시스템 호출을 통해 기존의 프로세스를 새로운 프로세스로 전환.
- 부모 프로세스는 여러 자식 프로세스를 가질수 있다.
- 프로세스의 트리 (계층 구조)를 형성한다.
- 프로세스는 자원을 필요로 하는데, 운영체제로부터 받으며 프로세스 간 공유할 수 있다.
자원의 공유 방식 3가지
- 부모와 자식이 모든 자원을 공유하는 모델
- 일부를 공유하는 모델
- 전혀 공유하지 않는 모델
→ 일반적으로 프로세스는 자원의 할당으로부터 경쟁관계이므로 대부분 공유를 하지 않는다.
수행 방식 2가지
- 부모 자식이 공존하며 수행되는 모델
- 자식이 종료될 때까지 부모가 wait()하는 모델
프로세스 관련 시스템 콜
fork()
- 새로운 프로세스를 부모 프로세스를 복제해서 생성한다.
- 부모를 그대로 복사 (Code, Data, Stack, binary and OS data)
- 주소 공간 할당 (Code, Data, Stack으로 이뤄진 가상 메모리 공간)
exec()
- (생성한, 기존) 프로세스 공간에 새로운 프로그램으로 덮어 씌워서 메인 메모리에 프로세스를 올려서 실행한다.
exit()
- 프로세스를 종료한다
- 프로세가 종료될 때 자식이 부모에게 output data를 보낸다 (부모는 wait() 중)
- 항상 자식이 먼저 죽고 부모가 이 후 일을 처리한다.
- 프로세스의 각종 자원들이 운영체제에 반납된다.
abort()
- 부모프로세스가 자식 프로세스의 수행을 강제로 종료 시키는 경우
- 자식이 할당 자원의 한계치를 넘어서서 사용하는 경우 (폭주)
- 자식에게 할당된 태스크가 더 이상 필요하지 않는 경우
- 부모가 종료하는 경우(exit), 부모가 종료되는 경우더라도 자식부터 단계적으로 죽고 부모가 죽는다.
- 운영체제는 부모 프로세스가 종료하는 경우 자식이 더이상 수행되도록 허용하지 않는다.
프로세스의 생성과 복사 : fork()
실행중인 프로세스를 복사하여 부모 프로세스와 똑같은 자식 프로세스를 생성한다.
즉, 부모의 주소공간 (Code, Data, Stack), Program Counter (프로세스의 instruction을 어디까지 실행했는지 나타내는 레지스터) 을 복제 생성.
- 부모와도 결국 자원을 경쟁하는 관계
- 단, 유닉스에서 Copy-On-Write(COW)의 형태로 Write명령이 오기 전까지는 일단 부모 프로세스를 공유하면서 존재하는 경우도 있다. write가 발생하여 새로운 공간을 가질때도 메인메모리에 올라간 부모 프로세스 코드 중 달라진 부분만 새로 갖고 최대한 공유를 지향하는 형태.
코드
int main()
{
int pid;
printf("Only parent\n");
pid = fork();
printf("\n PID : %d", pid);
// fork()가 일어나고 생성된 자식 프로세스는 부모의 Context를 복사
// 해서 생성되므로 생성된 바로 다음 위치부터 수행한다 (PC부터 인지)
if (pid == 0)
printf("\n hello, I am Child\n");
else if (pid > 0)
printf("\n hello, I am Parent\n");
return 0;
}
fork()가 실행되면 부모는 pid가 양수이고, 자식은 pid로 0을 부여해서 부모, 자식을 구분 짓는다
Only parent
PID : 7758
hello, I am Parent
PID : 0
hello, I am Child
fork() 시스템 호출로 복제되어 생성된 자식 프로세스가 별도로 갖는 값
- 프로세스 PID : 프로세서의 구분자가 새로 생성된다.
- 메모리 관련 정보 : 물리적 메모리의 상주 위치가 다르므로 새로 생성된다.
- 부모 프로세스 구분자 (PPID), 자식 프로세스 구분자 (CPID) : 부모 프로세스를 가리키는 값과 자식 프로세스를 가리키는 값이 변경된다.
fork() 시스템 호출의 장점
- 프로세서의 생성 속도가 빠르다.
- 프로그램을 새롭게 메모리에 올리는 것이 아니라, 이미 메모리에 올라온 프로세스를 메모리에 복사해서 생성하는 것이므로 빠르다. 크롬 새 창을 cmd + N으로 생성하면 더 빠른 이유이다.
- 추가 작업 없이 자원을 상속할 수 있다.
- 부모 프로세스가 특정 파일을 사용하기 위한 세팅이 된 경우 fork된 자식 프로세스는 바로 해당 파일을 사용할 수 있다.
- 시스템 관리를 효율적으로 할 수 있다.
- 부모, 자식 프로세스가 PID로 연결되어 있으므로 자식 프로세스가 종료되면 부모 프로세스가 사용하던 자원을 정리해줄 수 있다.
프로세스의 전환 : exec()
어떠한 프로세스를 완전히 새로운 프로세스로 태어나게 해준다. 프로세스는 가만히 두고 내용만 전부 변경한다. 이러한 목적은 이미 만들어진 프로세스의 구조를 재활용하기 위함이다.
코드
int main()
{
int pid;
printf("Only parent\n");
pid = fork();
printf("\n PID : %d", pid);
// fork()가 일어나고 생성된 자식 프로세스는 부모의 Context를 복사
// 해서 생성되므로 생성된 바로 다음 위치부터 수행한다 (PC부터 인지)
if (pid == 0){
printf("\n hello, I am Child. now I will run date~\n");
execlp("/bin/date", "/bin/date", (char*)0);
}
else if (pid > 0)
printf("\n hello, I am Parent\n");
return 0;
}
execlp() - 실행할 파일명을 두번적고, 매개변수를 큰따움표로 감싸서 콤마로 구분하여 넣은뒤 마지막에 (char*)0을 준다.
- execlp("echo", "echo", "3", (char*)0); → echo 3
fork()를 통해 부모를 복사한 프로세스가 태어났고, execlp()명령어를 통해 새로운 프로세스를 덮어씌어서 생성하는데, /bin/date의 프로세스를 실행하도록 하는 경우이다.
즉, 자식 프로세스가 fork()로 부터 생성되서 exec()을 실행해서 딴 함수로 간 후 종료되며, 다시 기존 프로세스(부모프로세스)로 돌아오지 않는다.
Only parent
PID : 8109
hello, I am Parent
PID : 0
hello, I am Child. now I will run date~
2021년 9월 19일 일요일 17시 39분 12초 KST
참고
exec()는 자식 프로세스가 아닌 기존의 프로그램에서도 사용할 수 있다
exec() 시스템 호출의 장점
- 새로운 프로세스를 만들려면 PCB를 새로 만들고, 해당 프로세스를 위한 메모리 공간을 확보하는 과정이 필요하다.
또한, 해당 프로세스의 종료 후 메모리 관리를 위해 상위 프로세스에 부모-자식 관계를 맺어 줘야 한다.
하지만, 이미 만들어진 프로세스에 exec()로 덮어씌운다면 이러한 과정을 생략해줄 수 있으므로 효율적이다.
wait()
해당 프로세스를 잠들게 해준다 (blocked)
- blocked는 보통 오래걸리는 event(I/O)를 경우 발생
- 부모 프로세스가 wait()시스템콜을 자식 프로세스를 생성한 후 호출하면,
자식 프로세스가 종료될 때까지 기다리면서 blocked된다. - 이후 자식 프로세스가 종료가 되면 부모 프로세스가 ready가 되고 실행이 된다.
대표적인 wait() - shell
- 쉘에서 입력을 기다리는 것 또한 사용자의 입력을 wait()하고 있는 것이고, 사용자가 입력한 프로세스를 처리하고 다시 부모 프로세스로 돌아가 wait()를 반복하게 되는 것이다
코드
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int pid;
int status;
printf("Only parent\n");
pid = fork();
printf("\n PID : %d", pid);
if (pid == 0)
{
printf("\n hello, I am Child.\n");
for (int i = 0; i < 10; i++)
printf("%d ", i);
printf("\n");
}
else if (pid > 0)
{
printf("\n hello, I am Parent. i will wating my child\n");
wait(&status);
printf("status : %d\n", status);
}
if (pid > 0)
printf("parnet is DONE\n");
else
printf("child is DONE\n");
return 0;
}
결과
Only parent
PID : 8516
hello, I am Parent. i will wating my child
PID : 0
hello, I am Child.
0 1 2 3 4 5 6 7 8 9
child is DONE
status : 0
parnet is DONE
exit()
프로세스를 종료한다
자발적 종료
- 사용자가 명시하지 않아도, 컴파일러가 프로그램이 끝나는 시점에 넣어놓게 된다 (마지막 statement 수행 후, main()함수가 리턴되는 위치에)
비자발적인 종료
- 부모프로세가 자식 프로세스를 종료 시키는 경우
- 한계치를 넘어서는 자원을 요청하는경우
- 자식에게 할당된 태스크가 더이상 필요하지 않는 경우
- 사용자가 키보드로 kill, break을 입력하는 경우 (control c 등)
- 부모가 종료하는 경우 (단, 자식부터 순차 종료되고 부모가 종료됨)
프로세스 간 협력 메커니즘 (IPC : Inter Process Communication)
독립적 프로세스 (Independent Process)
- 프로세스는 각자의 주소 공간을 갖고 수행되므로 원칙적으로 하나의 프로세스는 다른 프로세스의 수행에 영향을 주지 못한다
협력 프로세스 (Cooperating Process)
- 프로세스 간 협력 메커니즘을 통해 하나의 프로세스가 다른 프로세스의 수행에 영향을 미칠 수 있다
message passing
- 메시지를 전달하는 방법
- 커널을 통해 메시지를 전달한다.
- 프로세스 사이에 공유 변수(Shared variable)를 일체 사용하지 않고 통신하는 시스템.
- Direct와 Indirect 방법 두가지가 존재, 둘다 커널을 거쳐서 전달된다.
Direct Communication (통신 하려는 프로세스의 이름을 명시)
- 프로세스 P와 Q의 통신
- P : Q에게 메시지 전달
- Q : P에게서 메시지 받음
- send(Q, message) → Receive(P, message)
Indirect Communication (통신 하려는 프로세스의 이름을 명시하지 않음)
- mailbox (또는 port)를 통해 메시지를 간접 전달
- 누가 받을지 명시를 하지 않는다, 받을 프로세스는 그 mailbox에 접근해서 받으면 된다.
- P : 메일박스에 message 전달
- Q : 메일박스에서 message 받음
- Send (M, message) -> Receive (M, message)
- Process P → (Mailbox M) → Process Q
Shared memory
주소 공간을 공유하는 방법
- 프로세스의 주소공간을 메인 메모리에 Mapping할 때 공유해서 mapping한다. 이때 커널한테 공유를 요청해서 되는 것
- 공유된 이후에는 커널의 도움 없이 공유메모리를 사용해서 협력을 한다.
동 프로세스 내 Thread 간의 협력
- Thread는 하나의 프로세스내 CPU 수행 단위로서 프로세스간의 협력으로 볼수는 없지만, 동일 process를 구성하는 thread끼리는 주소공간을 공유하므로 협력이 가능하다. (스레드끼리는 강한 결합, 프로세스끼리는 약한 결합)
'CS > 운영체제 정리' 카테고리의 다른 글
4주차. CPU Scheduling (2) - FCFS, SJF, Priority, RR (0) | 2021.10.01 |
---|---|
4주차. CPU Scheduling (1) - CPU, I/O burst & 스케줄링의 기준 척도 (0) | 2021.10.01 |
3주차. Thread 정리 (0) | 2021.09.24 |
3주차. Process 정리(문맥교환, 상태, PCB, 스케쥴러) (0) | 2021.09.24 |
2주차. System Structure & Program Execution 2 (0) | 2021.09.17 |
- Total
- Today
- Yesterday