카테고리 없음

태스크 스크립터

Hans_S_92 2023. 1. 17. 11:54

프로세스의 속성 정보를 표현하는 가장 중요한 자료구조는 태스크 디스크립터를 나타내는 task_struct 구조체이다.

  • TCB (Task Control Block)
    • 임베디드 시스템에서 태스크 혹은 프로세스 정보를 표현하는 자료구조
  • struct task_struct [구조체 위치 include/linux/sched.h]
    • char comm[TASK_COMM_LEN]
    • 프로세스 이름을 저장함.
      • 실습?
      • 터미널에서 “ps -ely”입력하면 다음과 같이 출력한다.

위 사진에서 가장 오른쪽 systemd, kthreadd, … 등의 이름이 보인다. 프로세스 이름들은 태스크 디스크립터를 나타내는 task_struct 구조체의 comm 필드에 접근해서 출력하는 것이다.

linux/kernel/sched/core.c
/*
 * Mark the task runnable and perform wakeup-preemption.
 */
static void ttwu_do_wakeup(struct rq *rq, struct task_struct *p, int wake_flags,
               struct rq_flags *rf)
{
    check_preempt_curr(rq, p, wake_flags);
    p->state = TASK_RUNNING;
    trace_sched_wakeup(p);

#if 1 //HANS-STUDY
    if(!strcmp(p->comm, "kthreadd")) {
        printk("[+][%s] wakeup kthreadd process \n", current->comm);
        dump_stack();
    }
#endif
  • pid_t pid;
    • Process ID의 약자로 프로세스마다 부여하는 정수형 값
    • 프로세스가 생성될 때마다 증가함.
  • pid_t tgid;
    • 스레드 그룹 아이디를 표현하는 정수형 값.
    • 해당 프로세스가 스레드 리더일 경우 pid == tgid
  • volatile long state
    • 프로세스 실행 상태
해당 값에 들어가는 매크로
//?? 1 unrunnable, 0 runnable, >0 stopped: 
#define TASK_RUNNING            0x0000 //CPU에서 실행 중이거나 런큐 대기 상태
#define TASK_INTERRUPTIBLE      0x0001 //휴면 상태
#define TASK_UNINTERRUPTIBLE        0x0002 // 특정 조건에서 깨어나기 위한 휴면 상태
#define __TASK_STOPPED          0x0004
#define __TASK_TRACED           0x0008
  • 리눅스 시스템에서 확인대는 프로세스들은 대부분 TASK_INTERRUPTIBLE 상태다.
  • TASK_RUNNING, TASK_UNINTERRUPTIBLE 이 많은 경우 시스템 문제 의심
  • int exit_state;
    • 프로세스 종료 상태를 저장
    • 아래 중 하나의 값을 가짐.
/* Used in tsk->exit_state: */
#define EXIT_DEAD           0x0010
#define EXIT_ZOMBIE         0x0020
#define EXIT_TRACE          (EXIT_ZOMBIE | EXIT_DEAD)

 

  • int exit_code;
    • 프로세스의 종료 코드를 저장하는 필드
  • struct task_struct __rcu *real_parent; struct task_struct __rcu *parent;
    • real_parent > 자신을 생성한 부모프로세스의 태스크 스크립터 주소
    • parent > 부모 프로세스의 태스크 디스크립터 주소
    • 차이점? 일반적인 상황에서 자신을 생성한 부모 프로세스가 종료되지 않고 실행 중이면 real_parent와 parent가 같다. 그런데 부모 프로세스가 소멸될 경우가 있다. 이때 프로세스 계층 구조에서 지정한 부모 프로세스가 없을 경우 init 프로세스를 부모 프로세스로 변경한다.
  • struct list_head children; struct list_head sibling

부모 프로세스인 kthreadd 입장에서 태스크 디스크립터는 다음과 같이 구성된다.

  • struct list_head tasks;
    • list_head 구조체로서 연결 리스트 타입
    • 커널에서 구동 중인 모든 프로세스는 tasks 연결 리스트 등록
    • ? 프로세스의 태스크 디스크립터 필드 중 연결 리스트 타입인 tasks 필드는 언제 init 프로세스의 태스크 디스크립터 필드 중 연결 리스트 타입인 tasks 필드에 등록되느냐?
      • 프로세스는 처음 생성될 때 init_task 전역변수 필드인 tasks 연결 리스트에 등록함
    • u64 utime, stime
      • utime > 유저 모드에서 프로세스가 실행한 시간을 저장
      • stime > 커널 모드에서 프로세스가 실행한 시간을 저장