일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Bidirectional Associative Memory
- 하이퍼바이저
- Google App Engine
- NarwalFreo
- 패턴 인식
- 삼성전자 소프트웨어멤버십 SSM
- 구글 앱 엔진
- 동아리
- hopfield network
- Neural Network
- 물걸레자동세척로봇청소기
- 증강현실
- 신경회로망
- Friendship
- 멤버십
- 패턴인식
- 갤럭시탭S8울트라
- 나르왈프레오
- 물걸레로봇청소기추천
- 삼성소프트웨어멤버십
- Python
- 고려대학교
- 신경망
- 파이썬
- BAM
- SSM
- 인공지능
- 가상화
- 삼성
- 빅데이터
- Today
- Total
정보공간_1
[6기 강북 전영진] 리눅스 커널 심층 분석 #1 본문
#Intro
안녕하세요. 강북멤버십 23-2기 전영진입니다.
이번엔 리눅스 프로세스에 대해 소개하겠습니다.
#프로세스
프로세스는 실행 중인 프로그램을 나타냅니다.
사용중인 파일, 대기중인 시그널, 커널 내부 데이터, 프로세서 상태, 할당된 메모리 주소공간, 실행 중인 스레드 정보, 전역데이터 등 프로그램 코드를 실행하면서 생기는 모든 결과물을 지칭합니다.
여기서 커널은 이 모든 세부 사항들을 투명하고 효율적인 방식으로 관리합니다.
스레드는 프로세스 내부에서 동작하는 객체로, 각각의 스레드는 개별적인 프로그램 카운터, 프로세스 스택, 프로세서 레지스터를 가지고 있습니다. 커널은 프로세스가 아니라 이러한 각각의 스레드를 스케줄링 합니다.
참고로 리눅스에서는 프로세스와 스레드를 따로 구분하지 않습니다. 리눅스에서의 스레드는 조금 특별한 형태의 프로세스로 구분 지을 수 있습니다.
리눅스 커널은 프로세스 목록을 '태스크 리스트'라고 부르는 환형 양병향 연결리스트 형태로 저장합니다.
'태스크 리스트'의 각 항목은 <linux/sched.h>에 정의된 struct task_struct 형식으로 되어 있으며, '프로세스 서술자'라고 부릅니다.
프로세스 서술자에는 해당 프로세스와 관련된 모드 정보가 들어있습니다.
(사용중인 파일, 프로세스 주소 공간, 대기 중인 시그널, 프로세스의 상태 등)
#프로세스 서술자의 할당
struct task_struct 구조체는 객체 재사용 및 캐시 컬러링 기능을 지원하는 슬랩 할당자를 사용해 할당 합니다.
커널 2.6 이전에는 task_struct 구조체를 각 프로세스의 커널 스택 끝 부분에 저장 했지만, 이제는 슬랩 할당자를 이용해 동적으로 프로세스 서술자를 만드므로 thread_info라는 새로운 구조체를 스택 끝부분에 대신 두고 있습니다.
(thread_info 구조체에 프로세스 서술자 포인터가 들어있다.)
#프로세스 서술자 저장
시스템은 고유한 프로세스 인식번호, 즉 PID로 프로세스를 구분합니다.
기본적으로 초기 유닉스와 리눅스와의 하위 호환성을 문제로, PID의 최대값은 short int의 최대값인 32768이지만, <linux/thread.h> 파일을 통해 4백만으로 상향 조정할 수 있습니다. 근본적으로 PID 최대값은 시스템에 동시에 존재할 수 있는 최대 프로세스 수를 의미합니다.
커널 내부에서 태스크를 접근 할 경우에는 보통 task_struct 구조체의 포인터를 사용합니다. current_thread_info()함수를 이용하여 thread_info 구조체를 가져오고 task항목을 참조하여 task_struct 구조체의 포인터를 얻어옵니다.
• current_thread_info()->task;
#프로세스 상태
시스템의 프로세스는 다섯 가지의 상태중 하나에 속한다.
1. TASK_RUNNING : 프로세스가 실행 가능한 상태
현재 실행 중이거나 실행되기 위해 실행 대기열에 있는 상태.
2. TASK_INTERRUPTIBLE : 프로세스가 특정조건이 발생하기를 기다리며 중단된 상태.
조건이 발생하거나, 프로세스가 시그널을 받을 경우 TASK_RUNNING 상태로 바뀐다.
3. TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE와 비슷하지만 시그널을 받아도 실행 가능 상태로 바뀌지 않는다.
4. __TASK_TRACED : 디버거 등의 다른 프로세스가 ptrace를 통해 해당 프로세스를 추적하는 상태
5. __TASK_STOPPED : 프로세스 실행이 정지된 상태.
SIGSTOP, SGTSTP, SIGTTIN, SIGTTOU 같은 시그널을 받은 경우 이 상태가 된다.
커널 코드에서 set_task_state(task, state); 다음 함수를 사용하여 프로세스 상태를 변경할 수 있습니다.
#프로세스 계층 트리
리눅스 프로세스는 독특한 계층구조를 가지고 있습니다.
모든 프로세스는 PID가 1인 init 프로세스의 자식입니다. 시스템의 모든 프로세스는 하나의 부모 프로세스를 가지고, 또한 모든 프로세스는 하나 이상의 자식 프로세스를 가질 수 있습니다. 이러한 부모 자식 구조를 이용하면 시스템의 어떤 프로세스에서도 다른 특정 프로세스를 찾아 갈 수 있습니다.
#프로세스 생성
리눅스는 clone() 시스템 호출을 이용하여 fork()를 구현합니다.
(fork() : 기존 프로세스를 복사하여 새 프로세스를 생성)
1)fork(), vfork(), __clone() 라이브러리 함수 는 각자 적절한 플래그를 사용해
2)clone()함수 를 호출합니다. 그리고 clone() 시스템 호출은 다시
3)do_fork()함수 를 호출합니다.
결국 실제 프로세스 생성 작업은 kernel/fork.c에 정의된 do_fork() 함수에서 처리됩니다. do_fork() 함수에서는
4)copy_process() 함수 를 호출하고 프로세스 실행을 시작합니다.
#리눅스 스레드
리눅스 커널에서는 별도의 스레드 개념이 존재하지 않고, 기본적인 프로세스로 모든 스레드를 구현합니다.
그래서 리눅스 커널은 스레드를 위한 별도의 자료구조나 특별한 스케줄링 기법이 존재 하지 않습니다.
결국 스레드는 다른 운영체제에서는 무거운 프로세스에 비해 가볍고 빠르게 실행하는 기능을 제공하는 무언가이지만, 리눅스에서는 다른 프로세스와 자원을 공유하는 이미 충분히 경량화된 프로세스에 불과합니다.
다음 포스팅에서는 리눅스 커널의 프로세스 스케줄링에 대해 살펴 보겠습니다.
(Linux kernel development. 3/E 참조)
'IT 놀이터 > Elite Member Tech & Talk' 카테고리의 다른 글
[6기 신촌 류보원] 체감형 게임 - 오큘러스 리프트 연동 (0) | 2014.09.15 |
---|---|
[6기 신촌 김상훈] 텍스트 마이닝 #1 (0) | 2014.09.15 |
[6기 강북 윤덕진]Cross compile과 Bootloader (0) | 2014.09.15 |
[6기 전주 황규하] Tizen Platform 분석하기 - Tizen platform 개발환경 구축하기1 (0) | 2014.09.15 |
[6기 수원 최웅엽] c++ 을 이용한 디자인패턴 (0) | 2014.09.13 |