fork()는 프로세스를 생성하는 함수이고, clone()은 쓰레드를 생성하는 함수인데
커널 내부에서 마지막으로 호출되는 함수 do_fork()로써 동일한데 이런게 가능한 이유는 리눅스는
모두 task를 생성하기 때문이다.
fork()는 비교적 부모태스크와 덜 공유하는 task이고 clone()은 비교적 부모태스크와 많이 공유하는 task이다.
즉, do_fork()를 호출할 때 이 함수의 인자로 부모 태스크와 얼마나 공유할지를 정해 줌으로써,
fork()와 clone() 함수 둘 다를 지원 할 수 있는 것이다.
□ tgid(Thread Group ID)
시스템에 존재하는 모든 태스크는 유일하게 구분이 가능해야 한다. 태스크 별로 유일한 이 값은 task_struct 구조체 내의 pid 필드에 담겨있다.
그런데 POSIX표준에 의하면 '한 프로세스 내의 쓰레드는 동일한 PID를 공유해야 한다' 라고 명시 되어 있다.
리눅스에선 이를위해 tgid(Thread Group ID)라는 개념을 도입했다.
태스크가 생성되면 이 태스크를 위한 유일한 번호를 pid로 할당해준다. 그러다 사용자가 프로세스를 원하는 경우라면
생성된 태스크의 tgid값을 새로 할당된 pid값과 동일하게 넣어준다. 따라서 tgid 값도 유일한 번호를 갖게 된다.
사용자가 쓰레드를 원하는 경우라면 부모 쓰레드의 tgid 값과 동일한 값으로 생성된 태스크의 tgid를 설정한다.
결국 부모 태스크와 자식 태스크는 동일한 tgid를 갖게 되며 동일한 프로세스에 속해 있는 것으로 해석된다.
task_struct내의 tgid 값을 출력하는 함수 getpid()
task_struct내의 pid 값을 출력해 주는 함수는 gettid()
□태스크 문맥
태스크 문맥은 크게 세 부분으로 구분 할 수 있다.
첫 번째 문맥으로 태스크의 정보를 유지하기 위해 커널이 할당한 자료구조들이다.
대표적인 자료구조로는 task_struct, 파일 디스크립터, 파일 테이블, 세그먼트 테이블, 페이지 테이블 등이 있다.
두 번째 문맥 부분은 메모리 문맥으로 텍스트, 데이터, 스택, heap영역, 스왑 공간등이 여기에 포함된다.
세 번째 문맥 부분은 하드웨어 문맥으로 문맥 교환(context switch)할 때 태스크의 현재 실행 위치에 대한 정보를 유지하며,
쓰레드 구조 또는 하드웨어 레지스터 문맥이라고 불린다. 이 부분은 실행 중이던 태스크가 대기 상태나 준비 상태로
전이할 때 이 태스크가 어디까지 실행했는지 기억해 두는 공간으로, 이후 이 태스크가 다시 실행될 때
기억해 두었던 곳부터 다시 시작하게 된다.
'Linux > Kernels' 카테고리의 다른 글
태스크(task)관리-(5) (0) | 2016.09.02 |
---|---|
태스크(task)관리-(4) (0) | 2016.09.02 |
태스크(task)관리-(3) (0) | 2016.09.01 |
리눅스 커널 (0) | 2016.08.31 |
태스크(task)관리-(1) (0) | 2016.08.29 |
댓글