이 단원은 실용적인 부분들, 즉 실제로 손맛 느껴보는 단원이다. 그래서 이론 위주의 공부를 하고싶은 사람은 넘겨도 된다고 써있었다. 하지만, 그거 아는가? 답정너식 화법 말이다. “난 이거 너희들이 읽었으면 좋겠지만, 이론 위주의 공부만 할거라면 넘겨도 돼. 근데 난 너가 이걸 읽었으면 좋겠어. 여튼 그렇다고. 아 네버 마인드.”
아아아아 알았다고! 그래서 여튼 읽었다. 이 공부, 급하지 않으니까. 손맛 한 번 느껴보자(하면서 실상 코드 손으로 안침 ㅋ).
이 단원은 fork, wait, exec 함수를 실제로 사용해보면서 무슨 일이 일어나는지를 이해하는 것을 목적으로 하고 있었다. 그래서 사용해보면서 또 GPT 선생 붙잡고 내가 이해한 내용이 맞는지 체크를 받으면서 추가적인 이해를 더했다.
fork()
프로세스를 복제떠서 자식 프로세스로 실행하는 함수이다. 처음엔 현재 상태의 메모리 자원을 공유한다. 그러다 수정이 일어나는 시점에 해당 자원을 카피해서 독립성을 부여한다.
Copy-on-Write(COW)라 칭한다.
그리고 좀 더 파봤는데, 커널 객체는 공유되고, 스택/힙/전역변수와 같은 유저공간 데이터는 복사가 일어난다. 커널 객체는 기본적으로 파일 디스크립터(fd)가 가리키는 객체인데, 파일, 소켓 버퍼, 파이프 버퍼 등이 있다. 사실 그냥 입출력 객체는 다 fd로 접근한다.
pipe는
ls | grep hello할 때 그 pipe 맞다.
wait()
기다리는거 맞다. 누가 누굴 기다릴까? 부모가 자식을 기다린다.
exec()
다른 프로그램을 실행시켜서 프로세스를 전환하는 함수이다. 이 시점에서 프로세스는 전혀 다른 프로세스가 되어 있다. pid는 그대로다. 말 그대로 바꿔치기다.
왜 이걸 알아야 하는가
이게 미묘하다. 일반적인 케이스에서 이걸 다룰 일은 흔치 않다. 아니, 거의 없다고 봐도 무방하다. 하지만, OS관점에서 이 함수들은 아주 중요하다. OS가 하는 일 중 가장 중요한 일은 동시에 여러 프로세스를 돌리는 일이다. 그리고 OS도 하나의 프로그램이다. 즉, OS가 프로세스로서 다른 프로세스를 생성하고 관리하기 위해 fork, exec, wait은 필수불가결한 존재이다.
Process Control And Users
방금 본 저 3개의 함수 외에도, 프로세스를 컨트롤하는 함수들이 더 있다. 대표적으로 kill()이 있다. 말 그대로 kill이다. 근데, 죽인다고 생각하는게 아니라, 슬슬 꺼져랏! 하고 저주를 보내는 함수라고 보면 좋다. 프로세스로 시그널을 보내는 것이다. 익히 사용하는 Ctrl+C는 SIGINT, Ctrl+Z는 SIGSTOP이다. 둘 사이의 차이는, 쉽게 설명하면 “꺼져랏!”과 “비켜봐!”의 차이다. SIGINT는 정말 프로세스를 중단할 때 이용한다. 그에 반해, SIGSTOP은 잠시 멈춰주는 신호다. 실제로 프로세스의 state가 stop으로 변경된다. 그리고 그걸 다시 실행할 때는 fg 명령을 이용한다. 리눅스 사용하다가 간혹 Ctrl+Z를 잘못 누르면, 이렇게 살려내면 된다. 몰랐다면 참고 바람.
백그라운드 프로세스
SIGSTOP 후에 멈춘 프로세스는 백그라운드 프로세스가 아니다. 멈춰 있는 프로세스일 뿐이다. 이와 다르게, 백그라운드 프로세스는 돌고 있는 프로세스다. 단지 포그라운드가 아닐 뿐이다. 끝에&을 붙여서 실행한다던가 했을 때 생기는 프로세스가 백그라운드 프로세스다. SIGSTOP 후에는bg명령을 통해 백그라운드로 재개해야 백그라운드 프로세스로서 돌릴 수 있다.
프로그램에서 시그널을 받았을 때, 원하는 동작을 더 끼워넣으려면 signal() 함수를 이용해서 작정하면 된다.
그러면 한 가지 궁금증이 더해진다. 시그널은 어디로 들어올까? 부모? 자식? 알아보니, 해당 프로세스 그룹 전체에 도달한다. 부모와 자식 모두다.
다음은 유저로서 시그널을 어디까지 보낼 수 있는가에 대한 문제가 아직 남아있다. 기본적으로 시그널을 보낼 수 있는 대상은 같은 유저 소유의 프로세스에 한한다. 정리하면, 시그널은 같은 유저 소유의 프로세스 그룹에 보내진다.
그래서 이런 것도 가능하다. tty1에서 로그인한 후에 GUI를 올렸는데 그게 먹통이 되었다. 그럼 Ctrl+Alt+F#키를 이용해서 다른 tty로 진입하면 해결할 수 있다. 같은 유저로 로그인하거나, root로 로그인해서 그 GUI을 죽일 수 있다. 본체 버튼을 억지로 눌러서 비상종료할 필요가 없다.
RTFM: Read The Man Pages
동료에게 설명하기 귀찮을 때 RTFM을 시전하라고 한다. 이거 무슨 나같은 감성이다. 실제로 RTFM의 의미는 “Read The Fucking Manual”이라고 한다. 내 생각에 이건 그냥 “Read The Man Pages”로 풀어쓰는게 나을 듯 하다. 논쟁할 동료 학생이 없다. 회사에서 RTFM 그대로 쓰는 순간, 그냥 “책임지고 사퇴하겠습니다” 해야 한다. 만약 내가 RTFM을 외치면 퇴사 신호로 봐야 한다.
이후에 Useful Tools 챕터가 나왔는데, 리눅스 커맨드에서 자주 이용하는 기본 명령어들(ex. ps , top , kill)을 RTFM하라는 내용이라 굳이 남겨둘 만한 메모는 없다.