본문 바로가기

운영체제/과제 (OSTEP)

[운영체제][OSTEP][과제] 05. Process API (Simulation)

1. Run./fork.py-s 10 and see which actions are taken. Can you predict what the process tree looks like at each step? Use the -c f lag to check your answers. Try some different random seeds (-s) or add more actions (-a) to get the hang of it.

 

프로세스의 fork 및 exit 과정이 주어졌을 때 프로세스 트리가 어떻게 생겼는지 추정하는 문제이다. 생략!

 

2. One control the simulator gives you is the fork-percentage, controlled by the -f flag. The higher it is, the more likely the next action is a fork; the lower it is, the more likely the action is an exit. Run the simulator with a large number of actions (e.g.,-a 100) and vary the fork percentage from 0.1 to 0.9. What do you think the resulting final process trees will look like as the percentage changes? Check your answer with -c.

 

Fork의 확률을 더 높게 설정할수록 프로세스 트리가 커지고, 트리의 깊이도 깊어진다. 

 

3. Now, switch the output by using the-t flag (e.g., run ./fork.py-t). Given a set of process trees, can you tell which actions were taken?

 

ARG seed -1
ARG fork_percentage 0.7
ARG actions 5
ARG action_list
ARG show_tree True
ARG just_final False
ARG leaf_only False
ARG local_reparent False
ARG print_style fancy
ARG solve False

                           Process Tree:
                               a

Action?
                               a
                               └── b
Action?
                               a
                               └── b
                                   └── c
Action?
                               a
                               └── b
                                   └── c
                                       └── d
Action?
                               a
                               └── b
                                   └── c
                                       └── d
                                           └── e
Action?
                               a
                               └── b
                                   └── c
                                       └── d

 

첫 번째 Action에서 a는 b를 fork한다.

두 번째 Action에서 b는 c를 fork한다.

세 번째 Action에서 c는 d를 fork한다.

네 번째 Action에서 d는 e를 fork한다.

다섯 번째 Action에서 e가 exit한다.

 

4. One interesting thing to note is what happens when a child exits; what happens to its children in the process tree? To study this, let’s create a specificexample: ./fork.py-A a+b,b+c,c+d,c+e,c-. This example has process ’a’ create ’b’, which in turn creates ’c’, which then creates ’d’ and ’e’. However, then, ’c’ exits. What do you think the process tree should like after the exit? What if you use the-R flag? Learn more about what happens to orphaned processes on your own to add more context.

 

해당 플래그를 통해 fork.py를 실행할 경우의 결과이다.

ARG seed -1
ARG fork_percentage 0.7
ARG actions 5
ARG action_list a+b,b+c,c+d,c+e,c-
ARG show_tree True
ARG just_final False
ARG leaf_only False
ARG local_reparent False
ARG print_style fancy
ARG solve False

                           Process Tree:
                               a

Action?
                               a
                               └── b
Action?
                               a
                               └── b
                                   └── c
Action?
                               a
                               └── b
                                   └── c
                                       └── d
Action?
                               a
                               └── b
                                   └── c
                                       ├── d
                                       └── e
Action?
                               a
                               ├── b
                               ├── d
                               └── e

 

a는 b를, b는 c를, c는 d와 e를 차례대로 fork하지만,

d와 e의 부모 프로세스인 c는 자식 프로세스의 종료 전에 종료되어 버린다.

이 경우 d와 e는 고아 프로세스 (Orphan Process)가 된다.

 

하지만, 실행 결과를 보면 최상위 프로세스인 a에 의해 입양되었다 (re-parenting)

 

 

An orphan process is a computer process whose parent process has finished or terminated, though it remains running itself. 

In a Unix-like operating system any orphaned process will be immediately adopted by an implementation-defined system process: the kernel sets the parent to this process. This operation is called re-parenting and occurs automatically. Even though technically the process has a system process as its parent, it is still called an orphan process since the process that originally created it no longer exists. In other systems orphaned processes are immediately terminated by the kernel. Most Unix systems have historically used init as the system process to which orphans are reparented, but in modern DragonFly BSD, FreeBSD, and Linux systems, an orphan process may be reparented to a "subreaper" process instead of init.

(Wikipedia의 Orphan Process 문서)

 

Unix 기반의 운영체제에서 고아 프로세스를 어떤 프로세스가 입양할지는 구현에 따라 상이하다. 커널은 고아 프로세스에 부모를 할당하는데, 이 과정을 re-parenting이라 부르며, 자동적으로 발생한다.

 

고아 프로세스가 새로운 부모를 갖게 되었을지라도, 기술적으로는 여전히 고아 프로세스에 속한다. 원래 해당 고아 프로세스를 생성했던 부모가 더이상 존재하지 않기 때문이다.

 

Unix 기반의 운영체제가 아닌 다른 운영체제에서는 고아 프로세스가 커널에 의해 즉시 제거된다.

대부분의 Unix 기반 시스템들에서는 init을 시스템 프로세스로 가지고 있으며 고아 프로세스들은 init 프로세스에 입양된다.

 

하지만 현대의 DrangonFly BSD나 Free BSD, 그리고 리눅스 시스템의 경우 고아 프로세스는 아마 init 프로세스가 아닌 subreaper 프로세스에 의해 입양될 것이다. 

 

subreaper에 관한 내용을 다룬 Stack Overflow

https://unix.stackexchange.com/questions/250153/what-is-a-subreaper-process

 

What is a "subreaper" process?

The word "subreaper" is used in some answers. Searching Google also turn up entries where the word is "just used". How can I understand what a "subreaper" is?

unix.stackexchange.com

 

간략히 말하자면, 고아 프로세스의 조상 프로세스 중 subreaper로 지정된 가장 가까운 프로세스가 re-parenting을 수행한다. 과제에서 주어지는 코드는 일단 init 프로세스로 re-parenting을 수행하는 형태로 보인다.

 

 

하기한 코드는 -R 플래그를 추가하여 실행한 결과이다. local-reparent가 true로 바뀐 것을 보면, 지역적으로 re-parenting 수행을 가능하게 하는 플래그로 보인다.

ARG seed -1
ARG fork_percentage 0.7
ARG actions 5
ARG action_list a+b,b+c,c+d,c+e,c-
ARG show_tree False
ARG just_final False
ARG leaf_only False
ARG local_reparent True
ARG print_style fancy
ARG solve True

                           Process Tree:
                               a

Action: a forks b
                               a
                               └── b
Action: b forks c
                               a
                               └── b
                                   └── c
Action: c forks d
                               a
                               └── b
                                   └── c
                                       └── d
Action: c forks e
                               a
                               └── b
                                   └── c
                                       ├── d
                                       └── e
Action: c EXITS
                               a
                               └── b
                                   ├── d
                                   └── e

 

실행 결과, 최상위 프로세스인 a가 아닌 b 프로세스를 대상으로 re-parenting이 발생했다.

 

5. One last flag to explore is the -F flag, which skips intermediate steps and only asks to fill in the final process tree. Run ./fork.py-F and see if you can write down the final tree by looking at the series of actions generated. Use different random seeds to try this a few times.

 

플래그를 다르게 주며 최종 프로세스 트리를 그려보는 문제이다.

이 경우, 수행된 모든 Action(fork나 exit)의 순서와 종류를 파악할 수 있으므로 최종 트리 상태를 알 수 있다.

 

6. Finally, use both-t and -F together. This shows the final process tree, but then asks you to fill in the actions that took place. By looking at the tree, can you determine the exact actions that took place? In which cases can you tell? In which can’t you tell? Try some different random seeds to delve into this question.

 

랜덤하게 생성되는 프로세스 트리를 보고 어떤 Action이 수행되었는지를 추정할 수 있는지를 묻는 문제이다.

 

ARG seed -1
ARG fork_percentage 0.7
ARG actions 5
ARG action_list
ARG show_tree True
ARG just_final True
ARG leaf_only False
ARG local_reparent False
ARG print_style fancy
ARG solve False

                           Process Tree:
                               a

Action?
Action?
Action?
Action?
Action?

                        Final Process Tree:
                               a
                               ├── c
                               │   └── e
                               └── d

 

이 경우 5번의 Action이 수행되었다. b 프로세스가 없는 것을 보면, 생성 후 삭제되었음이 분명한데,

b 프로세스의 부모가 a였는지, c였는지, d였는지 추정이 불가능하다.

 

정리하자면, 제거된 프로세스의 부모가 누구였는지 추정이 불가능하다.

극단적으로 a의 자식 프로세스가 z만 남았고, action이 여러번 수행되었다면 그 사이에 발생한 Action은 추정이 불가능할 것이다.

 

 

ARG seed -1
ARG fork_percentage 0.7
ARG actions 5
ARG action_list
ARG show_tree True
ARG just_final True
ARG leaf_only False
ARG local_reparent False
ARG print_style fancy
ARG solve False

                           Process Tree:
                               a

Action?
Action?
Action?
Action?
Action?

                        Final Process Tree:
                               a
                               ├── b
                               │   └── c
                               │       ├── d
                               │       └── e
                               └── f

 

반면, 해당 프로세스는 발생한 Action의 수와 프로세스의 개수가 정확히 일치한다. 또한, 주어지는 프로그램의 특성상 알파벳을 통해 프로세스의 순서 또한 알 수 있다. 이 경우 추론이 가능하다. (a가 b를 fork, b가 c를 fork, c가 d와 e를 fork, a가 f를 fork...)

 

즉, 5번 6번 문제가 말하고자 하는 바는 다음이 아니었나 싶다.

 

1. 수행된 Action을 보고 최종 프로세스 트리의 모습을 추정하는 것은 가능하지만,

2. 최종 프로세스 트리의 모습만 보고 Action을 추정하는 것은 불가능한 경우가 존재한다.