School Lecture Study/Linux System Application Design

5. Process and Thread

vㅔ로 2022. 12. 20. 00:12
728x90

중앙대학교 3-2 리눅스 응용 설계 (손용석 교수님) 과목 정리입니다.

From a Program to a Process

Program

  • sequence of instructions + data + metadata for program loading and execution

Process in Linux

  • Process means “running program”
    • system에서 현재 실행되고 있는 program
  • whenever program / command is executed / issued in linux, it creates / starts a new process
    • pwd 가 실행되면 process가 시작된다.
  • Linux는 5자리 ID 번호로 process를 기록 → PID (process ID)
    • system의 각 process는 unique PID를 갖는다.
    • 사용된 PID는 새로운 process에서 재사용될 수 있다.

Creating process in user-level

fork system call

  • process 자신 : parent process
  • 복사된 process : child process
  • fork() system call을 사용하여 process 생성
    • fork() fail → return -1
    • fork() success
      • return 0 to child
      • return new process id to parent process

Example of fork system call

  • fork()의 값으로 parent, child process를 구분

Process descriptor : task_struct (in Linux)

  • kernel은 process의 list를 task list라 불리는 circular doubly linked list에 저장한다.
    • task의 각 element는 process descriptor이다. (linux/sched.h 에 선언)
    • struct task_struct 는 specific process의 모든 정보를 포함한다.
  • Managing a process as a task via struct task_struct

  • stack : memory stack
  • cpus_allowed : 어떤 task가 어떤 CPU에서 실행될 것인지 결정
  • mm : task의 주소
  • parent : task의 parent
  • children : task의 children list
  • sibling : task의 sibling list

Process states (in Linux)

Process states

  • TASK_RUNNING
    • The process is runnable
    • 현재 running task이거나 runqueue에서 실행되기를 기다리리는 process
    • user- or kernel-space의 task 모두 가능
  • TASK_INTERRUPTIBLE
    • process is sleeping ( = it is blocked) waiting for some condition
    • waiting condition이 true가 되었거나, signal을 받았을 때 kernel이 process 의 state를 TASK_RUNNING으로 설정
  • TASK_UNINTERRUPTIBLE
    • sending signal이 process를 깨우지 않는 것만 제외하고 TASK_INTERRUPTIBLE과 동일
    • interruption없이 process가 무조건 기다려야 할 때 사용
  • TASK_STOPPED
    • process 실행이 멈출 때
      • running, waiting 둘 다 아닐 때
      • task가 어떤 signal을 받을 때 process를 멈출 때 발생

Manipulating the current process state

  • kernel이 set_current_state(task, state) or set_task_state(task, state)를 사용하여 process의 state 변경

Example (Producer-Consumer)

  • Producer
    • event 발생시키고, consumer 깨우기
  • Consumer
    • event가 있는지 확인
    • list의 모두 보류중인 이벤트 처리
    • 아니면 producer가 consumer를 깨울 때까지 sleep

Procedure of Task Creation in Linux

fork()

  • caller task의 모든 state를 copy한 task 생성

clone()

  • caller task의 일부 state만 공유하는 task 생성
  • fork와 다르게 child process가 calling process의 execution context의 일부를 공유하도록 허용한다. (memory space, file descriptors 등)

clone flags

  • CLONE_VM
    • set : calling process, child process가 same memory space에서 실행
    • not set : clone이 일어날 때 child process가 calling process의 memory space의 separate copy에서 실행

_do_fork()

Main procedure in fork

  • current task를 복사한 new task 생성
  • 새로운 PID 할당
  • 생성된 task wakeup

Execution flow

  • Check flags
    • clone_flag가 invalid combination인 경우 error 리턴
    • CLONE_SIGHAND는 CLONEVM이 unset된 상태로 set 될 수 없다.
  • Duplicate task_struct
    • parent의 값 복사

  • check resource limits
    • resource가 limit을 초과한 경우 error
      • Ex. 지정된 UID에 허용되는 최대 작업 수
  • initialize task_struct
    • process relationships, scheduling statistics, other variables
  • Call sched_fork()
    • Scheduler-specific initialization
    • Ex. CFS가 parent의 남은 time slice를 child에게 분배

Sharing vs copying state “ABC”

Copy-on-Write

Copying address space

  • 모든 page frame을 copy하는 것은 시간이 너무 오래 걸림
  • ⇒ Copy-on-Write (COW) 사용

Copy-on-write (COW)

  • Optimization technique for copying resource
    • 실제 copy operation은 owner가 resource를 수정할 때까지 지연된다.
    • kernel의 많은 곳에서 사용 (fork, file systems, virtual memory, etc)

COW in do_fork()

  • actual write operation은 하지 않으니까 page frame은 share

  • parent나 child 둘 중의 하나라도 처음으로 값 수정이 일어난다면 그 때 page frame이 복사된다.

Code level analysis of _do_fork()

PID namespace

PID namespace

  • PID namespaces isolate the process ID number space, meaning that processes in different PID namespaces can have the same PID
    • container 내부의 process가 동일한 PID를 유지하는 동안 container의 process sets을 일시 중단/재개하고 container를 새 호스트로 migration합니다.
    • 새로운 PID namespace의 PID들은 독립된 system 처럼 1부터 시작한다.
    • fork(2), vfork(2), clone(2)를 호출하면 namespace 내부에서 unique한 PID를 갖는 process를 생성한다.

Code level analysis of _do_fork()

  • copy_files
    • child를 위해 열린 파일들의 정보를 관리하는 files_struct structure 생성
    • parents의 file_struct의 내용을 child로 복사한다.
    • CLONE_FILES flag를 사용하면 copy하지 않고 structure를 공유하고 reference count를 증가시킨다.
  • copy_fs
    • root와 current directory들을 관리하는 fs_struct structure를 생성한다.
    • parents의 fs_struct 복사
    • CLONE_FS flag를 사용하면 복사하지 않고 structure 공유하고 reference count 증가

이하 동일

Signal

Ctrl+C sends signal (SIGINT)

  • Ctrl+C를 누르면 interruptHandler 호출 → 종료

_do_fork() - copy_files()

  • parent task의 열려있는 file들을 child task로 복사

  • oldf : parent의 files
  • CLONE_FILES flag가 있으면 복사하지 않고 reference count만 증가 후 함수 탈출
  • dup_fd : 새로운 files 구조체를 할당하고 parent의 files 구조체의 내용을 복사해서 새로운 files 구조체에 복사한다.ㅇ
  • tsk→files = newf: 새로 만들어진 task(child)의 files를 업데이트한다.

 

  • newf: files_Struct allocate
  • spin_lock 실행 (file 보호)
  • old_fdt : parent task가 열려 있는 파일들을 저장한 fdtable을 가져온다.
  • old_fds : fdt의 file array를 가져온다.
  • old의 file수 만큼 new로 파일을 복사한다.
  • 복사가 끝나면 spin_unlock 호출

_do_fork() - copy_fs_struct()

  • fs_struct는 root directory 와 working directory를 관리한다.

  • fs : 새로운 fs_struct를 slab allocator를 사용하여 할당
  • spin_lock (다른 thread가 file 변경하지 못하도록)
  • root / pwd directory path 할당 → 빈번하게 사용되는 경로이므로 변수에 저장해놓는 것
  • path_get : directory entry와 vfsmount location의 reference count를 증가시킨다.
  • spin_unlock (lock release)

_do_fork() - copy_sighand()

  • CLONE_SIGHAND : flag가 enable되면 복사하지 않고 공유. reference count 1 증가
  • refcount_set : sig→count를 1로 초기화한다.
  • spin_lock_irq : irq가 siglock에 접근하지 못하도록 lock
  • memcpy로 parent의 sighand를 child의 sighand로 복사
  • spin_unlock_irq : lock release

Thread

General concept of thread

  • a thread is a basic unit of CPU utilization, consisting of a program counter, a stack, and a thread ID
  • a thread is part of execution within a process
    • process는 여러 개의 threads를 가질 수 있다.
    • multithreading?
      • thread는 lightweight process
      • process를 multiple threads로 나눠서 병렬화를 달성하기 위함
  • threads are concurrent flows of execution belong to the same program sharing the same address space
    • address space를 process와 공유함

Creating thread in User-level

  • Create a new thread
    • pthread_create(pthread_t thread, const pthread_attr_t attr,
      void *(
      start_routine)(void**), void *arg)
      • calling process에서 새로운 thread를 생성하는 함수
      • 새로운 thread는 start_routine을 호출하면 실행된다.
  • Join with a terminated thread
    • pthread_join(pthread_thread, void **retval)
      • thread가 지정한 thread가 종료될 때까지 기다린다.
      • failure to join with a thread that is joinable, produces a “zombie thread”
      • zombie thread는 일부 system resource를 사용한다.
  • Linux kernel은 pthread에 대해 clone() system call을 사용한다.

Creating thread - Code

  • pthread_create를 사용하여 thread 생성
    • pthread_t : thread ID를 나타내는 type
    • pthread_self() : thread ID를 return하는 함수
  • child thread 생성하고 tid_print로 PID 출력하기
  • tid_print가 끝나기를 기다림

Kernel thread is used to perform backgrond operations in the kernel

Ex. Daemon

Ex. kswapd, journald

→ user level thread와 매우 비슷하다.

→ 각 thread가 각각의 schedulable entity를 갖는다.

⇒ kernel thread를 생성하기 위해서는 kthread_create를 사용한다.

Kthread APIs

  • Creation APIs
    • kthread_create(threadfn, data, namefmt, arg...)
      • create a kernel thread
    • kthread_run(threadfn, data, namefmt, ...)
      • create a kernel thread with checking correct creation
  • Stop APIs
    • kthread_stop(struct task_struct *k)
      • stop (terminate) a created kernel thread
    • kthread_should_stop()
      • check a kernel thread to decide continue or stop (terminate)

Example

  • kthread_should_stop : thread가 멈출때까지 실행
728x90

'School Lecture Study > Linux System Application Design' 카테고리의 다른 글

6-2. Synchronization (2)  (1) 2022.12.20
6-1. Synchronization (1)  (0) 2022.12.20
4-2. Kernel module  (1) 2022.12.19
4-1. Design Principle of Linux Kernel  (0) 2022.12.19
3-2. System calls  (0) 2022.12.19