이로또

임베디드 리눅스 드라이버의 이해 6편: 커널 영역에서 쓰레드 만들기 본문

임베디드

임베디드 리눅스 드라이버의 이해 6편: 커널 영역에서 쓰레드 만들기

이로또 2025. 6. 4. 20:28

이 글에서는 리눅스 커널 영역에서 스레드를 생성하고 관리하는 방법을 정리합니다.

핵심 구조체인 task_struct를 중심으로 스레드 상태, 생성 및 종료 흐름, 주요 함수 사용법 등을 실제 예제 코드와 함께 설명합니다. 특히 kthread_create(), kthread_run(), kthread_should_stop(), kthread_stop() 함수의 역할과 차이점을 구체적으로 다루며, 스레드 상태 전이 흐름도 함께 제공합니다.


목차

  1. task_struct란?
  2. 주요 필드 설명
  3. 커널 스레드 상태 및 전이
  4. 커널 스레드 생성과 관리
    • kthread_create() vs kthread_run()
    • 주요 함수 정리
    • 예제 코드
  5. 스레드 종료 흐름과 주의사항
  6. 전체 요약

1. task_struct란?

task_struct는 리눅스 커널이 프로세스와 스레드를 관리할 때 사용하는 핵심 구조체로, 각 태스크의 상태, 우선순위, 메모리 정보 등을 저장합니다. 커널은 이 구조체를 통해 스케줄링 및 상태 전이를 관리합니다.


2. 주요 필드 설명

필드 설명
state 태스크의 현재 상태
*stack 커널 스택 포인터
prio, normal_prio 우선순위
sched_class, sched_entity 스케줄링 정보
cpu, cpus_allowed 할당된 CPU
mm, active_mm 사용자 공간 메모리 정보
exit_state, exit_code 종료 상태
tasks 태스크 링크드 리스트

3. 커널 스레드 상태 및 전이

상태값 예시

의미
-1 실행 불가능
0 실행 가능
>0 대기 중 (sleep)

상태 전이 흐름

[NEW] → [TASK_RUNNING] ↔ [TASK_RUNNING]
                ↓
   [TASK_INTERRUPTIBLE / UNINTERRUPTIBLE]
                ↓
           [TASK_ZOMBIE]

 

상태 설명
TASK_RUNNING 실행 중 또는 대기 큐에 있음
TASK_INTERRUPTIBLE 시그널로 깰 수 있는 대기
TASK_UNINTERRUPTIBLE 시그널로 깨지 않는 대기
TASK_STOPPED 정지된 상태
TASK_ZOMBIE 종료 대기 중

4. 커널 스레드 생성과 관리

kthread란?

  • 2.6 커널 이후 도입된 고수준 스레드 API
  • ps 명령어 시 [이름] 형식으로 출력됨

주요 함수

함수 설명
kthread_create() 생성만 수행 (실행은 wake_up_process()로)
kthread_run() 생성과 실행을 동시에 수행
kthread_should_stop() 종료 요청 확인용
kthread_stop() 스레드 종료 요청 및 정리 수행

예제 코드

static struct task_struct *my_kthread;

int my_thread_fn(void *data) {
    while (!kthread_should_stop()) {
        printk("running in kernel thread\n");
        ssleep(1);
    }
    return 0;
}

static int __init my_module_init(void) {
    my_kthread = kthread_run(my_thread_fn, NULL, "kthread_example");
    return 0;
}

static void __exit my_module_exit(void) {
    if (my_kthread)
        kthread_stop(my_kthread);
}

5. 스레드 종료 흐름과 주의사항

종료 방식

  • kthread_stop() 호출 시 내부적으로 종료 플래그 설정
  • 스레드 함수 내 반복문에서 kthread_should_stop()을 체크해야 정상 종료됨

반환값

  • kthread_stop()은 thread_fn()의 반환값을 리턴함
int thread_fn(void *arg) {
    while (!kthread_should_stop()) {
        printk("Thread working...\n");
        ssleep(1);
    }
    return 123;
}

// 외부에서
int ret = kthread_stop(task);  // ret == 123

6. 전체 요약

개념 함수 설명
task_struct 태스크의 모든 정보를 담는 커널 구조체
kthread_create() 스레드 생성 (비활성 상태)
kthread_run() 생성 + 실행
kthread_stop() 종료 요청 및 정리
kthread_should_stop() 종료 여부 확인
종료 방식 자발적 종료를 유도함 (flag 기반)