Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

00
0
0


[리눅스커널] 프로세스: 프로세스란 4. 프로세스(Process) 관리

프로세스라는 용어는 추상적이고 다양한 의미를 담고 있어 프로세스가 무엇인지를 다양한 관점으로 바라볼 수 있습니다.

프로세스란 무엇일까요? 간단히 말해서 프로세스(process)는 리눅스 시스템 메모리에서 실행 중인 프로그램을 말합니다. 스케줄링 대상인 태스크와 유사한 의미로도 쓰입니다. 다수의 프로세스를 실시간으로 사용하는 기법을 멀티프로세싱이라고 하며, 같은 시간에 여러 프로그램을 실행하는 방식을 멀티태스킹이라고 합니다.

우리가 쓰고 있는 스마트폰의 동작 방식을 잠깐 떠올려 봅시다. 전화를 하면서 메모를 남기고, 음악을 들으면서 웹 브라우저를 사용할 수 있습니다. 여러 애플리케이션이 동시에 실행됩니다. 이것은 멀티태스킹을 통해 프로그램을 시분할 방식으로 처리하기 때문에 가능합니다.

이번에는 리눅스 개발자 입장에서 프로세스가 무엇인지 생각해 봅시다. 프로세스는 리눅스 시스템 메모리에 적재되어 실행을 대기하거나 실행하는 실행 흐름을 의미합니다. 여기서 다양한 의문이 생깁니다. 

 프로세스가 실행을 대기한다면 실행할 때 어떤 과정을 거칠까? 
 프로세스는 어떤 구조체로 식별할까? 

프로세스를 관리하는 자료구조이자 객체를 태스크 디스크립터(task descriptor)라고 부르고 task_struct 구조체로 표현됩니다. 이 구조체에 프로세스가 쓰는 메모리 리소스, 프로세스 이름, 실행 시각, 프로세스 아이디(PID), 프로세스 스택의 최상단 주소와 같은 속성 정보가 저장돼 있습니다.

그렇다면 프로세스를 task_struct라는 구조체로만 표현할 수 있을까요? 앞에서 프로세스란 실행 흐름 그 자체라고 정의했습니다. 프로세스의 실행 흐름은 어느 구조체에 저장할 수 있을까요? 이 질문에 다음과 같이 대답할 수 있습니다.

 프로세스의 실행 흐름을 표현하는 또 한 가지 중요한 공간은 프로세스 스택 공간이며, 이 프로세스 스택의 최상단 주소에 thread_info 구조체가 있다.

그럼 다음 함수의 실행 흐름을 보면서 프로세스의 실행 흐름에 대해서 배워봅시다.

1 -000|__schedule()
2 -001|schedule_timeout()
3 -002|do_sigtimedwait()
4 -003|sys_rt_sigtimedwait()
5 -004|ret_fast_syscall(asm)

위와 같은 함수 목록을 처음 보면 낯설겠지만 차근차근 보면 그리 어렵지 않을 것입니다. 이 함수의 실행 흐름으로 다음과 같은 사실을 알 수 있습니다.

함수 호출 방향은 5번째 줄에서 1번째 줄 방향이다. 
유저 공간 프로그램에서 sigtimedwait() 함수를 호출하면 이에 대응하는 시스템 콜 핸들러 함수인 sys_rt_sigtimedwait() 함수가 호출된다.
1번째 줄의 __schedule() 함수가 호출돼 스케줄링된다.

프로세스는 함수를 호출하면서 함수를 실행합니다. 그렇다면 함수를 호출하고 실행할 때 어떤 리소스를 쓸까요? 바로 프로세스 스택의 메모리 공간입니다. 모든 프로세스들은 커널 공간에서 실행될 때 각자 스택 공간을 할당받으며 스택 공간 내에서 함수를 실행합니다. 

앞에서 본 프로세스가 스케줄러에 의해 다시 실행된다고 가정해 봅시다. 이후 어떻게 실행될까요?

1 -000|__schedule()
2 -001|schedule_timeout()
3 -002|do_sigtimedwait()
4 -003|sys_rt_sigtimedwait()
5 -004|ret_fast_syscall(asm)

1번 함수에서 5번 함수 방향으로 되돌아올 것입니다. 그럼 여기서는 어떤 정보를 참고해서 이전에 실행됐던 함수로 되돌아갈까요? 

프로세스가 마지막에 실행했던 레지스터 세트와 실행 흐름은 프로세스 스택 공간에 저장돼 있었습니다. 여러분이 A() 함수에서 B() 함수를 호출하고, B() 함수에서 C() 함수를 호출하는 코드를 작성했다고 가정해 봅시다. C() 함수가 실행을 마무리하면 B() 함수에서 A() 함수로 되돌아갑니다. 이 같은 원리입니다.

정리하면 프로세스는 어느 정도 추상적인 개념을 내포합니다. 하지만 리눅스 커널에서 프로세스를 표현할 수 있는 다음과 같은 자료구조가 있습니다.

task_struct 구조체: 태스크 디스크립터
thread_info 구조체: 프로세스 스레드 정보

프로세스에 대해 처음 공부를 시작하는 분들은 보통 “프로세스를 잘 알려면 뭘 알아야 할까?”라는 질문을 많이 합니다. 프로세스가 무엇인지 잘 알려면 앞에서 소개한 프로세스 속성 정보와 실행 흐름을 저장하는 구조체를 잘 알아야 합니다. 프로세스를 제어하는 함수들은 위 구조체를 중심으로 실행되기 때문입니다.  

다음 절에서는 프로세스와 함께 자주 쓰는 용어인 태스크에 대해 살펴보겠습니다.

#프로세스

프로세스 소개 
프로세스 확인하기  
프로세스는 어떻게 생성할까?  
유저 레벨 프로세스 실행 실습  
커널 스레드  
커널 내부 프로세스의 생성 과정   
프로세스의 종료 과정 분석  
태스크 디스크립터(task_struct 구조체)  
스레드 정보: thread_info 구조체  
프로세스의 태스크 디스크립터에 접근하는 매크로 함수  
프로세스 디버깅  
   * glibc의 fork() 함수를 gdb로 디버깅하기  


"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)


# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2







핑백

덧글

  • 2019/04/02 21:44 # 답글 비공개

    비공개 덧글입니다.
  • 2019/04/03 12:40 # 비공개

    비공개 답글입니다.
  • 지나가는설인 2019/08/19 21:59 # 삭제 답글

    글 잘 읽었습니다. 상세한 설명 정말 감사드려요! 9월에 책 내시는 것 맞나요? 나오면 꼭 사고싶네요
  • AustinKim 2019/08/19 22:01 #

    응원해주셔서 감사합니다. 책은 10월 이후에 출간될 것 같습니다.
    자주 블로그에 오셔서 유용한 정보 얻어 가셨으면 좋겠습니다.
댓글 입력 영역